目录
由于最近的几个项目都有接触到Cython的使用,也积累了一些Cython的经验,于是决定把续上(蜜汁发现刚好过了一年。。),将Cython的一些用法记录下来。这一些文章可以作为一些学习的参考,不过kick-start的话还是去看看之前的博文以及官方的例子吧~
Cython对C/C++内置类型的支持
Cython在类型设置上和C/C++是十分相似的,不仅默认支持基本C类型int
、float
、unsigned long
等等以及他们的指针类型,还支持C的struct
、union
、enum
以及C++的cppclass
(即C++中的类)。需要注意的是在Cython中,定义C/C++对象都需要使用cdef关键字,或者使用cpdef关键字定义一个Python封装过的对象。另外Cython还通过ctypedef
支持C/C++形式的typedef。下面是一些定义变量的例子:
|
|
size_t
和Py_ssize_t
也是受Cython语言支持的类型。如果想使用uint32_t
形式的类型,则需要添加from libc.stdint cimport uint32_t
形式的语句。- 这些变量的作用域定义与Python是相同的,但是cdef定义的对象是不能import到Python代码中的,而cpdef定义的对象则可以。
Cython对Python内置类型的支持
尽管Cython兼容Python的语法,但是我们还可以通过cdef来使得Python对象具有静态类型,以提高运行效率。Cython在除了支持Python内置的list
、dict
、tuple
外,还支持直接声明Python的基本类型,这需要通过from cpython cimport int
形式的语句来实现。此外有一类特殊的类型是ctuple
,能够直接定义tuple中元素的类型与数量,有些类似于C# 7中的语法,例子如下:
|
|
Cython的类型映射
在将Python的基本类型对象与C/C++的基本类型对象进行相互赋值的过程中,Cython会进行自动的类型转换,可识别的转换规则有:
C types | From Python types | To Python types |
---|---|---|
[unsigned] char, [unsigned] short, int, long | int, long | int |
unsigned int, unsigned long, [unsigned] long long | int, long | long |
float, double, long double | int, long, float | float |
char*1 | str/bytes | str/bytes |
C array2 | iterable | list |
struct | union | dict |
如果自动类型转换不被支持、或者自动转换类型不是所需类型的话,还可以使用强制类型转换,语法是在变量前加<type-name>
,例如
|
|
如果使用
<type-name?>
形式则会在转换时执行运行时检查
Cython中的模板
Cython还支持C++中的模板,语法是class_name[template_args]
,不过模板参数目前只支持类型参数,因此更像是C#中的泛型。对模板的支持不仅是可以声明模板类,还可以支持绑定已有C++的模板类,这也是Cython区别于Boost.Python、Pybind11等C++端绑定库的重要一点。由于后者在编译期无法了解Python代码的使用需求,因此只能在编译器展开模板(Instantiation),而Cython则可以通过.pxd
头文件保留模板的格式,在引用该库需要编译时再展开。
模板的应用例子如下:
|
|