1. 什么是Cython?
Cython是Python的一个扩展模块,使用静态类型注释来拓展Python语言,快速的编译并且实现高性能的C扩展模块。其目的是说明Python代码的静态类型并转换代码,安全地以C语言的形式呈现出来。Cython还可以轻松地与C代码集成,同时允许使用C语言的函数和数据结构。
2. 安装Cython
Cython可以使用Python包管理器pip进行安装。在终端输入以下命令即可:
pip install cython
3. Cython代码编写
3.1 基本语法
Cython程序的结构和Python类似。定义函数、类和变量的方式与Python相同。Cython可以使用Python模块,但对于Cython模块必须在Cython代码中导入。下面让我们来看看Cython的编码风格。
cdef float f(float x, float y):
return x**2 + y**2
cpdef int distance(a, b):
cdef int dx = abs(a[0] - b[0])
cdef int dy = abs(a[1] - b[1])
return dx**2 + dy**2
cdef 声明C语言静态类型,而cpdef声明同时具有Cython和Python的定义,使得Cython模块可以在Python中使用。在上面的代码中,f()
函数声明了两个浮点数类型的形参,并返回一个浮点数类型。而distance()
函数声明一个元组类型的形参,并返回一个整型。同时函数体内定义了两个整型变量,变量类型通过 cdef关键字进行声明。
3.2 Cython模块
在Cython模块中,可以像Python模块一样定义 setup.py
文件和 __init__.py
文件。在 setup.py
中使用Cython命令的扩展进行编译。使用cythonize()
构建扩展模块。那么我们以Damerau-Levenshtein algorithm(DAMLE)为例,来展示Cython的模块应用。
3.3 DAMLE实现
DAMLE算法是一个字符串匹配算法,用于计算字符串间的编辑距离。实现DAMLE算法需要用到Python循环语句的效率较低。而Cython可以用 for
循环加快执行速度。下面展示了DAMLE算法的Cython实现:
def damle_distance_cython(str1, str2):
cdef int d, i, j, k, m, n
m = len(str1)
n = len(str2)
dist = [[0 for j in range(n+1)] for i in range(m+1)]
for i in range(1, m+1):
dist[i][0] = i
for j in range(1, n+1):
dist[0][j] = j
for i in range(1, m+1):
for j in range(1, n+1):
if str1[i-1] == str2[j-1]:
cost = 0
k = j-1
else:
cost = 1
for d in range(i,0,-1):
if str1[d-1] == str2[j-1]:
k = d-1
break
else:
if dist[d][j-1] + 1 < cost:
cost = dist[d][j-1] + 1
k = d-1
elif dist[d-1][j-1] + 1 < cost:
cost = dist[d-1][j-1] + 1
k = d-2
if i > 2 and j > 2 and str1[i-1] == str2[j-2] and str1[i-2] == str2[j-1]:
cost = dist[k][j-2] + 1
dist[i][j] = cost
return dist[m][n]
这个Cython代码中使用了静态声明,替代了Python中的动态变量声明。静态声明可以让Cython增加类型检查,从而在代码转换之前降低错误率并提高速度。此外,静态类型声明还可以将Python转换为C代码,增强可扩展性。
4. 编译Cython代码
4.1 生成.pyx文件
首先,我们需要将Cython代码转换成Python包。可以使用.pyx
文件作为Cython模块。方便导入和使用的.py
文件可以被Cython编译器自动生成。
def damle_distance_cython(str1, str2):
# Your Code Here
return dist[m][n]
保存.pyx
文件后,使用以下命令将其转换成Python包:
cython foo.pyx -o foo.c
上述命令可以将.pyx
文件编译成C代码并输出到.c
文件中。
4.2 生成.so文件
Cython可以通过使用.c
文件进行编译,以生成一个动态链接库或共享对象文件.so
。使用以下命令进行编译:
gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I$PYTHON/include/python3.8 -o foo.so foo.c
然后,就可以将foo.so
文件移动/复制到Python库路径下的包目录中,要运行Cython模块,还需要将Python路径添加到系统环境变量当中,这样Python可以搜索并找到.so
文件。
5. 总结
Cython是一个非常有用的工具,支持Python语法和静态类型操作。使用Cython可以将Python代码转换成C代码的形式,从而支持更快的执行速度,支持静态语言的类型安全以及编译支持。
Cython的语法良好,视觉上更类似于Python。Cython代码可以被直接转换成Python代码,同时增强了代码性能。同时,Cython还可以使用简单的接口与C代码集成。Cython代码的一个优点是,它可以被重新编译为不同平台的原生代码,从而支持不同类型的硬件和操作系统。
虽然Cython非常有用,但是它并不是Python的替代品。对于那些只依赖于Python标准库的程序,Cython并没有明显的优势。但对于那些依赖于速度的程序,Cython是学习和掌握的好工具。