-
说明
尝试翻译Cython Documentation以助学习。
水平有限,乐迎指正;文档首页:《Cython官方文档中文翻译》
-
Cython基础
Cython
的根本特性可以总结如下:Cython
是带有C
数据类型的Python
Cython
就是Python
:Python
的几乎所有代码都是有效的Cython代码。(虽然也有一些局限( Limitations),但就目前而言还是非常接近的)Cython
编译器将代码转为C代码
,从而实现对Python/C API
的平等调用。因为变量和参数可声明为
C数据类型
,故Cython
能量远不止此。控制Python值
和C值
的代码可以自由融合,当需要时则自动转换。Python
的引用计数维护和错误检查以及全部错误处理功能也都是自动的,其中就包括try-except
、try-finally
语句(即便是在处理C数据的过程中) -
Cython实现Hello World
鉴于
Cython
可以识别任意有效的python源文件,开始时的困难之一就是搞懂如何编译你的扩展。让我们从标准的python
hello world
开始:print("Hello World")
将上述代码保存在一个
helloworld.pyx
文件内,然后创建setup.py
文件,这是一个Makefile(更详细了解参见 Source Files and Compilation),setup.py
文件内容如下:from distutils.core import setup from Cython.Build import cythonize setup(ext_modules=cythonize("helloworld.pyx"))
上述准备好两个素材文件,使用下述命令行命令创建
Cython文件
:$ python setup.py build_ext --inplace
上述命令会在本地文件夹内创建一个
helloworld.so
(unix系统)或helloworld.pyx
(windows系统)文件。现在来使用这个文件,打开一个Python 解释器(在命令行中cmd > python
),之后类似引入常规模块一样import
这个文件:>>> import helloworld Hello world
恭喜你!你现在就知道如何构建一个Cython扩展了。但是,这个例子并没有体现出使用Cython的必要性,下面让我们来看一个更实用的例子。
译者注:详细实现过程及可能出现问题,参见《Cython使用案例之:输出Hello World》
-
pyximport:面向开发人员的Cython编译
如果你的模块无需其他C库或特殊的构建设置(build setup),那么你可以采用
pyximport
模块,最初由Paul Prescod开发,用import直接导入*.pyx文件,这样就避免每次更新代码后都单独重新执行运行setup.py的动作。与Cython*绑定安装,实用方法如下:>>> import pyximport; pyximport.install() >>> import helloworld
译者注:上述代码在cmd > python解释器中运行,会直接实现编译过程并导入,文件夹中并不生成
.pyx
、.c
文件。Pyximport模块还对普通Python模块提供了实验性编程支持,这允许你在每一个
Python
导入(import)的*.pyx和.py模块上运行Cython
,包括标准库和后续安装的包。当然,还有很多模块是Cython
编译不了的,在这种情况下,import机制将返回去加载Python
源模块。.py*的导入机制如下:>>> pyximport.install(pyimport=True)
不建议在最终用户端实用*Pyximport构建代码,因为其与import*系统挂钩。适合最终用户端的方式是提供以轮包(wheel packaging format)形式存在的预构建(pre-built)的二进制包。
-
斐波那契(Fibonacci)的乐趣
Python官方教程有定义一个简单的fibonacci函数:
from __future__ import print_function def fib(n): """ Print the Fibonacci series up to n """ a, b = 0, 1 while b < n: print(b ,end= '') a, b = b, a + b print()
按照Hello World例子的步骤,先创建一个*.pyx扩展,比如fib.pyx*,然后创建一个setup.py,直接实用Hello World例中的setup.py,只需要更改
Cython文件
的名字和生成模块
的名字,如下:from distutils.core import setup from Cython.Build import cythonize setup(ext_modules = cythonize("fib.pyx"))
创建扩展的命令与用于helloworld.pyx的命令是一样的:
$ python setup.py build_ext --inplace # 文件所在路径下,命令行中运行
使用新的扩展:
>>> import fib >>> fib.fib(2000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
译者注:
同样,可以采用pyximport来实现上述编译过程:
# 第一步:命令行进入python $ py # 本机需要用py表示python3 # 第二步:在python中采用pyximport编译 >>> import pyximport;pyximport.install() >>> fib # 第三步:在python内调用fib模块的fib函数 >>> fib.fib(2000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
-
质数
这里是个小例子,展示Cython功能。也是一个常规功能:找质数(素数)的个数。
你告诉他你需要多少个质数,它给你返回一个包含所需质数的list:
prime.pyx文件
def primes(int nb_primes): cdef int n, i, len_p cdef int p[1000] if nb_primes > 1000: nb_primes = 1000 len_p = 0 # p中当前元素数量 n = 2 while len_p < nb_primes: # 判断n是否质数 for i in p[:len_p]: if n % i == 0: break # 如果上述循环未中断程序,那我们就得到了一个质数 else: p[len_p] = n len_p += 1 n += 1 # 以Python list形式返回结果 result_as_list = [prime for prime in p[:len_p]] return result_as_list
-
References
来源:CSDN
作者:Quant_Learner
链接:https://blog.csdn.net/The_Time_Runner/article/details/103647041