前言:这遍文章,是翻译自官方文档,觉得原官方文档的例子有些抽象,所以我用一些具体的示例代码替换了。
Python作为一种动态语言, 它鼓励的编程风格优先考虑类和对象的方法和属性方面,而不是它们如何适合哪种类继承结构。
这可以使Python成为一种非常轻松和舒适的快速开发语言,但需要付出代价 - 管理数据类型的繁重工作会被转嫁到解释器上。在运行时,解释器需要搜索命名空间,获取属性以及解析参数和关键字元组方面会消耗大量的时间。这种运行时“后期绑定”是Python相对缓慢的主要原因。而Cython就使用类似于C++"早期绑定的"技术,并且保留了大部分C/C++的特性,在编译静态版本的扩展库后,速度基本上等同于C/C++的运行速度.
C变量和类型定义
cdef语句用于声明C变量,无论是本地变量还是模块级变量:
cdef int age;
cdef float score;
//声明一个结构体
cdef struct Person:
int age
char* name
#end-cdef
注意Structs可以声明为cdef packed struct,它与C指令具有相同的效果
将枚举声明为cpdef将创建一个PEP 435样式的Python包装器:
目前没有用于定义常量的特殊语法,但您可以为此目的使用匿名枚举声明,例如:
cdef enum:
OPEN=1
CLOSE=0
#end-cdef
注意:struct,union和enum仅在定义类型时使用,而不是在引用它时使用。 例如,要声明一个指向Person的指针变量,你会写:
cdef struct Person:
char* name
int age
#end-cdef
/**正确写法**/
cdef Person *jk
/*错误写法*/
cdef struct Person *jk
cdef 还可以用于声明属于c / cython的函数
cdef int add(int a,int b):
return a+b
#end-cdef
Cython中有三种函数定义:
- def:Python函数是使用def语句定义的,就像在Python中一样。它们将Python对象作为参数并返回Python对象。
- cdef:Cython函数使用新的cdef语句定义。它们将Python对象或C值作为参数,并且可以返回Python对象或C值。
- cpdef:Hybrid函数(别以为是某田的混动技术-___,-),允许从任何地方调用cpdef声明的混合函数,但在从其他Cython代码调用时Hybrid函数会获得C一样的速度。
即使从Cython调用,也可以通过子类或实例属性上的Python方法覆盖cpdef声明的方法或属性。如果发生这种情况,就得不到性能的提升,即使它没有被覆盖,跟调用cdef方法相比,从Cython调用cpdef方法的开销很小,可以忽略不计。
Cython函数中的参数
可以使用常规C声明语法将任一类型的函数的参数声明为具有C数据类型。 例如:
当Python函数的参数声明为具有C数据类型时,它将作为Python对象传入,并在可能的情况下自动转换为C值。 请看如下示例:
//python函数
def eat(int n,char* food):
return f'今天我吃了{n}次{food}'
#end-def
/*等价于*/
def eat(n,food):
cdef int i=n
cdef char* food=food
return f'今天我吃了{n}次{food}'
#end-def
目前,只能对数字类型,字符串类型和结构体进行自动转换(以递归方式组合任何这些类型); 尝试将任何其他类型用于Python函数的参数将导致编译时错误。在处理字符串的时候,在调用一个引用后必须确保该指针是否正被用, 可以从Python映射中获取结构,如果要在函数返回后,在处理字符串的时候,必须确保该指针是否正在使用。另一方面,Cython函数可以具有任何类型的参数,因为它们是使用普通的C函数调用直接传递的。
使用带有Python对象返回类型的cdef声明的函数(如Python函数),当执行离开函数体而没有显式返回值时,将返回None值。这与C / C ++形成对比,后者使返回值未定义。 在非Python对象返回类型的情况下,返回等价于零的值,例如,0表示int,False表示bint,NULL表示指针类型。
网友评论