- 背景介绍:
Cython是一种针对Python语言与Cython扩展语言进行优化的静态编译器。通过编写Cython接口代码,可以让Python代码与C/C++代码无缝衔接,达到为Python加速的目的。当然,也可以完全通过Cython接口重构Python代码,直接提速Python。整个过程可以表示为:首先将Cython接口代码转化为C/C++代码,然后将C/C++代码编译为动态链接库.pyd(Windows下)或.so文件(Linux下),即:
Cython接口代码 $\rightarrow$ C/C++代码 $\rightarrow$ .pyd/.so动态库
如果接口编写得当,通过Python调用该动态库文件较原生Python代码可提速两个量级。
在语法层面,Cython几乎支持所有的Python语法,并且额外加入了一些C/C++的等效写法(提速的关键)。因此,在编写接口代码的时候势必两种写法都会用到,从而造成混乱。本文将主要介绍笔者习惯的Cython接口写法规范,可能会比较抽象。关于语法细节,建议参考官方文档:https://cython.org/
>>>使用规范<<<
- Python接口端:实现Cython与Python之间的交互(支持缺省参数)
- def $\rightarrow$ 函数接口
- cdef class $\rightarrow$ 类接口
此种情况下,类对象中self只能索引已存在的对象,不能直接创建新内容,功能上与this指针基本对标,此即self限制。
- C++接口端:实现Cython与C++之间的交互(不支持缺省参数)
- cdef $\rightarrow$ 函数接口
- cdef struct $\rightarrow$ 类接口,不支持函数重载
- cdef cppclass $\rightarrow$ 类接口,支持函数重载
- 常见操作:
- 头部distutils标签:
# distutils: language = c++
- 加载cython模块:
from libcpp.vector cimport vector from libcpp.string cimport string
- 加载外部C++头文件及源文件:
cdef extern from '*.h': ... cdef extern from '*.cpp': pass
- 头部distutils标签:
- 细节问题:
- setup.py文件中,sources参数必须保证加载到所有涉及到的C++源文件,但是不能重复加载;
- 当需要实例化一个C++接口下的类时,必须确保该类至少持有默认构造函数;
- 接口使用bool类型不安全。