使用Cython为Python写扩展1:初识Cython,,使用Cython为P
使用Cython为Python写扩展1:初识Cython,,使用Cython为P
使用Cython为Python写扩展1:初识Cython
Cython使为Python写C扩展就如同写Python代码一样简单。广泛用于数学软件包,SAGE公司,作为执行快速,可扩展的运算。它提供了安全和可维护的方法通过自动生成所需代码来构建原生Python模块。
我们经常会使用Cython将C/C++实现的系统绑定到Python中,这样我们就可以使用Python来处理高级别逻辑,原生模块来处理底层代码。
关于示例
代码
http://git.oschina.net/erhuabushuo/learning-cython
版本:
Python:3.3Cython:0.19注意:如果你使用的版本不一致,可能需要对示例进行适当修改
安装Cython
我们先来安装Cython。将Cython想象成类似Bison, flex,或者GCC,它接受输入源代码并生成其他编译和链接代码:
Fedora: yum install Cython3Ubuntu/Debian: apt-get install Cython3curl -O http://www.cython.org/release/Cython-0.19.tar.gztar xzvf Cython-0.19.tar.gzcd Cython-0.19sudo python3 setup.py installWindows http://wiki.cython.org/InstallingOnWindows .pip: pip3 install cython你好中国
我们通过以下来检查cython的安装
$ cython3 --versionCython version 0.19
hello.pyx
print("你好中国!")
这里Cython代码仅简单打印出"你好中国!"
Makefile
all: cython3 -3 -o hello.c hello.pyx gcc -g -O2 -fpic -c hello.c -o hello.o `python3.3-config --cflags` gcc -g -O2 -shared -o hello.so hello.o `python3.3-config --libs`
编译链接
$ make
现在我们已经创建了hello.so模块。
使用
python3Python 3.3.2+ (default, Feb 28 2014, 00:52:16) [GCC 4.8.1] on linuxType "help", "copyright", "credits" or "license" for more information.>>> import hello你好中国!>>>
我们直接通过import导入模块
解释
Cython使用.pyx和.pxd作为文件扩展名。现在我们仅关心.pyx文件。后面,我会介绍.pxd的使用。
我们来看看Cython是如何工作的
创建你自己的模块
现在已经看到了”你好中国“模块,让我们看看如何写你自己的模块,你可以链接你自己的一些代码,稍后,我们会介绍如何包装你的代码。
执行你的C代码
Cython时Python的超集,虽然语法和关键字都可相同工作,我们也应该弄清Python和Cython区别。让我们来构建类似hello-world风格模块,但做一些其他简单事情。
mycode.c
#include <stdio.h>int myfunc(int a, int b){ printf("现在我们在C代码\n"); return a + b;}
这是我们要调用的C代码,执行简单的运算两个数之和函数。现在我们使用Python来调用它。打开文件mycode.h,定义Cython的原型。
mycode.h
#ifndef __MYCODE_H__#define __MYCODE_H__extern int myfunc(int, int);#endif //__MYCODE_H__
我们需要这样让Cython可以知道需要调用的函数原型。在实际中,你可能已经在项目头文件中定义了原型。新建mycodecpy.pyx,写入如下代码:
cdef extern from "mycode.h": cdef int myfunc(int, int)def callCfunc(): print(myfunc(1, 2))
在Cython代码里,我们定义了我们想使用的C代码,cdef关键字标识要链接的C代码。现在我们已经定义了所要使用的头文件,我会详细说明Python如何调用原生代码,由于直接调用C代码时危险的。所以,Cython为我们处理所有类型转换问题。基本函数包装,callCfunc,调用myfunc函数并且传递整型,然后简单打印结果。
用以下命令编译:
$ cython3 mycodecpy.pyx$ gcc -g -O2 -fpic -c mycode.c -o mycode.o$ gcc -g -O2 -fpic -c mycodecpy.c -o mycodecpy.o `python3.3-config --cflags`$ gcc -shared -o mycodecpy.so mycode.o mycodecpy.o `python3.3-config --libs`
我们要链接mycode.c代码。将所有C文件编译为对象文件,然后将所有对象文件链接成一个二进制文件。因此,所以确保你链接了所有需要对象文件。
$ python3>>> from mycodecpy import callCfunc>>> callCfunc()现在我们在C代码3
所以,我们现在已经编译并且通过Python代码来调用我们原生代码。你卡亚开始绑定一些其他一些原生模块了。
类型转换
你也许注意到了我们调用直接调用Cython函数而没带参数,如果我们想带参数呢?
def callCfunc(int x, int y): print(myfunc(x, y))
现在我们增加了两个int参数到我们定义的Python包装函数中。这里需要Python代码类型安全的转换PyObjects为C类型。当你创建一个Python整型对象。该类型不是integer而是PyObject。如果你想在C中使用,你需要通过Python C API来获取该值,但是Cython自动给你做了该事情。例如,如果你传递了不合法参数,你将会得到:
>>> callCfunc(1, ‘string‘)Traceback (most recent call last): File "<stdin>", line 1, in <module> File "mycodecpy.pyx", line 4, in mycodecpy.callCfunc (mycodecpy.c:687) def callCfunc(int x, int y):TypeError: an integer is required
添加更多类型安全对象,你发现会提高速度,代码也会更漂亮。因为Cython编译器可以更加优化代码避免使用Python调用。
使用Cython为Python写扩展1:初识Cython,布布扣,bubuko.com
使用Cython为Python写扩展1:初识Cython
评论关闭