我是靠谱客的博主 机智毛巾,最近开发中收集的这篇文章主要介绍C语言扩展Python,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Python具有很好的开发灵活性,最大的特点是C语言可以对Python进行扩展,目前工作中正在进行相关的开发,第一篇文章作为基础.

实现C函数,用Python API封装,实现俩个功能,1.say_hello,打印hello world! 2.calc_pv,做加法用算.

以下为使用方法:

01 Python 2.7.3 (default, Nov 13201211:17:50)
02 [GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
03 Type "help""copyright""credits" or "license" for more information.
04 >>>
05 >>> import session
06 >>>
07 >>> session.sayhello()
08 hello world!
09 >>> session.sum(1,2)
10 3
11 >>>
以下为实现的步骤,核心的地方在代码里加了注释.


01 /**
02  *
03  *  $ cpython_eg1.c version1.0 2012-11-13 xxx $
04  *  @2012 xxx.com.cn
05  *
06  */
07  
08 #include "Python.h"
09  
10 static PyObject *say_hello(PyObject *self)
11 {
12     printf("%sn","hello world!");
13     /** python 没有void 类型,在没有返回值的时候,必须使用Py_RETURN_NONE*/
14     Py_RETURN_NONE;
15 }
16  
17 static PyObject *calc_pv(PyObject *self,PyObject *args)
18 {
19  
20     int i_ct=0;
21     int j_ct=0;
22     /** PyArg_ParseTuple 用来解析参数,PyArg_ParseTuple
23       (PyObject *args, const char *format, ...)*/
24     /** i代表int,同理s代表char *,d代表double,多个参数可以直接使用'is'这样使用,'|'代表或的意思,
25             代码中'|'最后一个i是可选参数*/
26     if (! PyArg_ParseTuple(args, "i|i", &i_ct,&j_ct))
27         return NULL;
28     return Py_BuildValue("i", (i_ct+j_ct));
29 }
30  
31 /*
32  * Function table
33  * PyMethodDef结构体定义:
34  * struct PyMethodDef {
35  *   const char *ml_name;   // The name of the built-in function/method
36  *   PyCFunction  ml_meth;  // The C function that implements it
37  *   int         ml_flags;  // Combination of METH_xxx flags, which mostly
38  *                 describe the args expected by the C func
39  *   const char *ml_doc;    // The __doc__ attribute, or NULL
40  *  };
41  *
42  */
43  
44 static PyMethodDef addMethods[] =
45 {
46      // METH_NOARGS 无参数
47     {"sayhello",(PyCFunction)say_hello,METH_NOARGS,"say hello!"},
48      // METH_VARARGS 带有参数
49     {"sum",(PyCFunction)calc_pv,METH_VARARGS,"calc pv"},
50     /**NULL代表结束位,Py_InitModule会以NULL代表函数列表结束*/
51     {NULL, NULL, 0, NULL}
52 };
53  
54 /*
55  * Initialize
56  *
57  * 如果定义模块名字为session,必须要有initsession(void)函数作为动态接口
58  * Python会自动寻找接口调用
59  */
60  
61 PyMODINIT_FUNC initsession(void)
62 {
63     PyObject *module;
64     /** Initialize module ,addMethods是需要初始化的函数列表*/
65     module = Py_InitModule("session", addMethods);
66     if (!module)
67         return;
68 }

最后是编译的过程,首先创建setup.py,内容如下

1 from distutils.core import setup, Extension
2  
3 module1 =  Extension('session',sources=['cpython_eg1.c'],language='c')
4  
5 setup (name = 'emar_py_lib', version = '1.0',
6        description = 'This is a demo package',
7        ext_modules = [module1])
编译过程为:

1.python setup.py build

2.sudo python setup.py install

转自:http://my.oschina.net/max1984/blog/89122?from=20121118

上次实践的是在工作中写的小程序,也是Python扩展的基础,在上一个例子C语言扩展Python(一)中其实核心在于对Python参数的解析,Python.org提供了很丰富的解析规则,几乎任何类型(基础类型、对象类型等).推荐官网链接说明:
http://docs.python.org/2/c-api/arg.html.

Python编写中,经常用到关键词参数传递,例如:

1 def fun(arg0,arg1=None,arg2=None):
2     print "%s %s %s" % (arg0,arg1,arg2)
3  
4 def main():
5     fun('hello',arg2='!',arg1='world')
6  
7 if __name__ == '__main__':
8     main()
输出:
1 >> hello world !

C语言扩展也可以实现,参数解析我们使用PyArg_ParseTupleAndKeywords方法做解析.该方法定义的原型为:

1 /* Support for keyword arguments donated by
2    Geoff Philbrick <philbric@delphi.hks.com> */
3  
4 /* Return false (0) for error, else true. */
5 int
6 PyArg_ParseTupleAndKeywords(PyObject *args,
7                             PyObject *keywords,
8                             const char *format,
9                             char **kwlist, ...)
下面是在例子  C语言扩展Python(一)  基础上增加,实现一个关键词参数传递的方法.
01 /**
02  * python中经常会使用关键词参数
03  * 例如:
04  *     def func(a,arg1='hello') ...
05  * C扩展也可以实现该形式的调用,只是使用不一样的解析参数函数
06  */
07 static PyObject *print_kw(PyObject *self,PyObject *args,PyObject *kw)
08 {
09     static char *kwlist[] = { "arg0","arg1",NULL};
10     char* hello="default";
11     char* world="default";
12     if (!PyArg_ParseTupleAndKeywords(args,kw,"s|s",kwlist,&hello,&world)) {
13          printf("ERROR");
14          return NULL;
15     }
16     printf("%s %sn",hello,world);
17     Py_RETURN_NONE;
18 }

kwlist[] 定义出我们关键词参数key的名字,不难看出我们定义俩个关键词参数arg0与arg1,接下来就是向Python暴露该方法.
详细参考下方代码段.

01 static PyMethodDef addMethods[] =
02 {
03      // METH_NOARGS 无参数
04     {"sayhello",(PyCFunction)say_hello,METH_NOARGS,"say hello!"},
05      // METH_VARARGS 带有参数
06     {"sum",(PyCFunction)calc_pv,METH_VARARGS,"calc pv"},
07      // METH_VARARGS 带有关键字参数
08     {"print_args",(PyCFunction)print_kw,METH_KEYWORDS,"print argument keyword"},
09     /**NULL代表结束位,Py_InitModule会以NULL代表函数列表结束*/
10     {NULL, NULL, 0, NULL}
11 };

METH_KEYWORDS代表该方法是关键词参数类型.接着我们按照C语言扩展Python(一)方法重新编译setup.py.并进行测试

01 Python 2.7.3 (default, Nov 13201211:17:50)
02 [GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
03 Type "help""copyright""credits" or "license" for more information.
04 >>> import session
05 >>> help(session)
06 Help on module session:
07  
08 NAME
09     session
10  
11 FILE
12     /usr/local/lib/python2.7/site-packages/session.so
13  
14 FUNCTIONS
15     print_args(...)
16         print argument keyword
17      
18     sayhello(...)
19         say hello!
20      
21     sum(...)
22         calc pv
23  
24  
25 >>> session.print_args('hello')
26 hello default
27 >>> session.print_args(arg0='hello')
28 hello default
29 >>> session.print_args(arg0='hello',arg1='world!')
30 hello world!
31 >>>

转自:http://my.oschina.net/max1984/blog/89435

最后

以上就是机智毛巾为你收集整理的C语言扩展Python的全部内容,希望文章能够帮你解决C语言扩展Python所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(69)

评论列表共有 0 条评论

立即
投稿
返回
顶部