如文章《加速python,保护你的源代码 》所述,”Cython是Python的一个扩展模块,主要功能是将Python代码编译成C/C++,然后再编译成Python扩展(Windows下为.pyd,Linux下为.so)”
其主要作用是:
- 隐藏 Python 源代码
- 加速
Cython 可以通过 cdef、cpdef等声明静态变量,获得更高的效率提升
详细的官方开发文档
使用方法
- 安装Cython
easy_install -U cython
- 编写 .pyx 源文件
- 编写 setup.py
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules=cythonize("test.pyx"),
)
- 编译 .pyx 文件生成扩展
python setup.py build_ext
语法细节
最简单的方式就是直接将普通的 .py 文件重命名为 .pyx
但因为动态变量的原因,这种方法对效率提升不大,并且也没办法使用 C-API
def、cdef 和 cpdef
主要参考文章《Cython中def,cdef,cpdef的区别》
- def 用来在 Python 层面中声明一个函数
- cdef 用来在 C 层面中声明变量及函数
- cpdef 会使得 Cython 产生一个 cdef 函数和一个 def 函数
- cdef 修饰的函数比 def 的函数调用更快(内部执行都是一样的)
- cpdef 修饰的函数会同时生成 C 和 Python 下的接口
- def 下不允许再嵌套 cdef 函数,因为 Python 不识别 C 函数指针
# WON'T WORK!
def g(a):
cdef (int b):
return a+b
声明方法
主要参考文章《C 函数的调用》
1)变量声明
cdef 修饰下可以声明 C 类型的变量及 python 对象
cdef int variable
cdef float* variable
cdef np.ndarray[np.float32_t, ndim=2] variable #python对象
2)类实例变量声明
cdef class dtmfDetector:
cdef int GOERTZEL_N, SAMPLING_RATE, debug
cdef int* freqs
def __init__(self, int pfreq=8000):
self.GOERTZEL_N = 92
self.SAMPLING_RATE = 8000
self.freqs = [697,770,852,941,1209,1336,1477,1633]
调用C/C++标准库
Cython 自带 C/C++ 标准库
Python27\Lib\site-packages\Cython\Includes\libc
Python27\Lib\site-packages\Cython\Includes\libcpp
import 格式示例
import cython
from libc.stdlib cimport atoi
from libc.string cimport memset
调用C/C++源文件的函数和类(混合编程)
cdef extern from "otherfile.h":
int myCFunc() #myCFunc()在otherfile.h声明,可能在otherfile.c定义
cppclass MyCPlusClass: #在otherfile.h声明,可能在othercplusfile.cpp定义
MyCPlusClass()
char* strstr(const char *haystack, const char *needle)
def pythonFunc():
cdef MyCPlusClass* newclass = new MyCPlusClass()
cdef MyCPlusClass newclassInStack
print(myCFunc())
newclass.strstr(needle='akd', haystack=data)
newclassInStack.strstr(needle='akd', haystack=data)
del newclass #创建在堆上面的对象需要手工销毁