zoukankan      html  css  js  c++  java
  • Python和C扩展实现方法

    一、Python和C扩展

    cPython是C编写的,python的扩展可以用C来写,也便于移植到C++.

    编写的Python扩展,需要编译成一个.so的共享库。

    Python程序中。

    官方文档:https://docs.python.org/2/extending/extending.html#writing-extensions-in-c

    二、举例

    >>> import spam
    >>> status = spam.system("ls -l")

     我们需要创建一个spam.c的文件模块,这个模块是C实现。开头必须有

      #include <Python.h>

     下面实现以上的举子:

    static PyObject *
    spam_system(PyObject *self, PyObject *args)
    {
        const char *comment;
        int sts;
    
        if (!PyArg_ParseTuple(args, "s", &command))
            return NULL;
        sts = system(command);
        return Py_BuildValue("i", sts);
    }
    
    

    上述函数的Python扩展中C函数有两个参数:self, args,这两个是必须的。

    三、模块方法和函数初始化

    1、定义模块及帮助文档。模块叫system,指定执行函数spam_system, 帮助文档“Execute a shell command”

    static PyMethodDef SpamMethods[] = { 
        {"system", spam_system, METH_VARARGS, "Execute a shell command."},
        {NULL, NULL, 0, NULL}
    };

    在编译完之后,导入模块,执行如下help命令,就会出现文档

    In [5]: help(spam)
    
    
    Help on module spam:
    
    NAME
        spam
    
    FILE
        /usr/lib/python2.6/site-packages/spam.so
    
    FUNCTIONS
        system(...)
            Execute a shell command.

    2、初始spam,初始化模块函数一定要init[module],保持一致

    void initspam() {
        Py_InitModule("spam", SpamMethods);
    }

    三、编译

    1、编译模块时,需要编写setup.py文件

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    from distutils.core import setup, Extension
    
    MOD = "spam"
    setup(name=MOD, ext_modules=[Extension(MOD, sources=['spam.c'])])

    模块名name和扩展模块。

    2、进行编译

    [root@local PycExt]# python setup.py build
    running build
    running build_ext
    building 'spam' extension
    gcc -pthread -fno-strict-aliasing -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -D_GNU_SOURCE -fPIC -fwrapv -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/usr/include/python2.6 -c spam.c -o build/temp.linux-i686-2.6/spam.o
    In file included from /usr/include/python2.6/pyconfig.h:4,
                     from /usr/include/python2.6/Python.h:8,
                     from spam.c:3:
    /usr/include/python2.6/pyconfig-32.h:1034:1: warning: "_POSIX_C_SOURCE" redefined
    In file included from /usr/include/stdio.h:28,
                     from spam.c:1:
    /usr/include/features.h:162:1: warning: this is the location of the previous definition
    In file included from /usr/include/python2.6/pyconfig.h:4,
                     from /usr/include/python2.6/Python.h:8,
                     from spam.c:3:
    /usr/include/python2.6/pyconfig-32.h:1043:1: warning: "_XOPEN_SOURCE" redefined
    In file included from /usr/include/stdio.h:28,
                     from spam.c:1:
    /usr/include/features.h:164:1: warning: this is the location of the previous definition
    gcc -pthread -shared build/temp.linux-i686-2.6/spam.o -L/usr/lib -lpython2.6 -o build/lib.linux-i686-2.6/spam.so

    生成一个build的文件夹,里面有spam.so库

    [root@local PycExt]# ls
    build  setup.py  spam.c

    3、安装

    [root@local PycExt]# python setup.py install
    running install
    running build
    running build_ext
    running install_lib
    copying build/lib.linux-i686-2.6/spam.so -> /usr/lib/python2.6/site-packages
    running install_egg_info
    Removing /usr/lib/python2.6/site-packages/spam-0.0.0-py2.6.egg-info
    Writing /usr/lib/python2.6/site-packages/spam-0.0.0-py2.6.egg-info

    执行命令如上,就安装好了。

    四、使用模块

    In [1]: import spam
    
    In [2]: spam.system("ls -la")
    total 20
    drwxr-xr-x.  3 root root 4096 Apr  8 22:07 .
    drwxr-xr-x. 10 root root 4096 Apr  8 21:01 ..
    drwxr-xr-x.  4 root root 4096 Apr  8 21:51 build
    -rw-r--r--.  1 root root  171 Apr  8 21:48 setup.py
    -rw-r--r--.  1 root root  549 Apr  8 22:07 spam.c
    Out[2]: 0
    
    In [3]: 

    如上,即为python扩展相关内容...

    spam.c

    #include <stdio.h>
    #include <stdlib.h>
    #include "Python.h"
    
    
    static PyObject *
    spam_system(PyObject *self, PyObject *args)
    {
        const char *command;
        int sts;
    
        if (!PyArg_ParseTuple(args, "s", &command))
            return NULL;
        sts = system(command);
        return Py_BuildValue("i", sts);
    }
    
    static PyMethodDef SpamMethods[] = {
        {"system", spam_system, METH_VARARGS, "Execute a shell command."},
        {NULL, NULL, 0, NULL}
    };
    
    void initspam() {
        Py_InitModule("spam", SpamMethods);
    }
    
    int main(int argc, char *argv[])
    {
        return 0;
    }

    setup.py

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    from distutils.core import setup, Extension
    
    MOD = "spam"
    setup(name=MOD, ext_modules=[Extension(MOD, sources=['spam.c'])])
  • 相关阅读:
    机器学习第二章复习
    机器学习第三章复习
    机器学习第四章复习
    第一次作业
    第二次作业
    第06组 Beta版本演示
    第06组 Beta冲刺(4/4)
    第06组 Beta冲刺(3/4)
    第06组 Beta冲刺(2/4)
    第06组 Beta冲刺(1/4)
  • 原文地址:https://www.cnblogs.com/zhuangzebo/p/4403664.html
Copyright © 2011-2022 走看看