Cython 既是一个优化的静态编译器,也是一个 Python 的超集的编程语言的名称。作为
编译器,它可以使用 Python/C API 执行源到源的编译,把本地 Python 代码及其 Cython 方言
编译为 Python C 扩展。它允许你结合 Python 和 C 的威力,而不需要手动处理 Python/C API。
Cython 作为源码编译器
对于使用 Cython 创建的扩展,你将获得的主要优势是使用它提供的语言超集。总之,
你可以利用源到源的编译,使用纯 Python 代码创建扩展。这是 Cython 最简单的方法,因
为它几乎不需要对代码进行任何修改,就可以显著的提升性能,并且开发成本也非常低。
Cython 提供了一个简单实用的 cythonize 函数,允许你轻松地将编译过程与
distutils 或 setuptools 集成。假设我们想把一个纯的 Python 实现的 fibonacci()函
数编译成一个 C 扩展。如果它位于 fibonacci 模块中,最小的 setup.py 脚本,如下所示:
from setuptools import setup
from Cython.Build import cythonize
setup(
name=‘fibonacci’,
ext_modules=cythonize([‘fibonacci.py’])
)
Cython 用作 Python 语言的源代码编译工具有另一个好处。源到源编译到扩展可以是源
分发安装过程的完全可选部分。如果需要安装软件包的环境没有 Cython 或任何其他构建前
提条件,则可以将其安装为普通的纯 Python 包。用户不需要关注以这种方式分发的代码有
任何功能性的行为差异。
分发使用 Cython 构建的扩展的常见方法是打包 Python/Cython 源以及从这些源文件生
成中的 C 代码。这样,根据当前构建前提条件,包可以以 3 种不同的方式安装。
● 如果安装环境没有可用的 Cython,则扩展 C 代码是从提供的 Python/Cython 源中生成。
● 如果 Cython 不可用,但有可用的构建前提条件(C 编译器,Python/C API 头),扩
展是从分散式的预生成的 C 文件中构建。
如果前面的先决条件都不可用,并且扩展是从纯 Python 源创建的,则模块将像普
通 Python 代码一样安装,并跳过编译步骤。
注意,包含生成的 C 文件以及 Cython 源文件,这是 Cython 文档中推荐的分发 Cython 扩展
的方式。文档中还提到,默认情况下应该禁用 Cython 编译,因为用户在他的环境中可能没有所
需的 Cython 版本,这可能会导致意想不到的编译问题。不过,随着环境隔离的出现,现今这似
乎是一个不太令人担忧的问题。此外,Cython 是一个有效的 Python 包,它在 PyPI 上可用,因此
你可以很容易地定义特定版本的项目依赖。包含这样一个先决条件,无疑是一个有严重影响的决
定,应该非常仔细地考虑。更安全的解决方案是利用 setuptools 包中 extras_require 特
性的强大功能,并允许用户决定是否要使用具有特定环境变量的 Cython,如下所示:
import os
from distutils.core import setup
from distutils.extension import Extension
try:
只有当 Cython 可用时
cython 源到源的编译才可以使用
import Cython
并且特定的环境变量明确说明
使用 Cython 生成 c 源码
USE_CYTHON = bool(os.environ.get(“USE_CYTHON”))
except ImportError:
USE_CYTHON = False
ext = ‘.pyx’ if USE_CYTHON else ‘.c’
extensions = [Extension(“fibonacci”, [“fibonacci”+ext])]
if USE_CYTHON:
from Cython.Build import cythonize
extensions = cythonize(extensions)
setup(
name=‘fibonacci’,
ext_modules=extensions,
extras_require={
通过’[with-cython]'这个特性
当包被安装时
可以设置特定的 Cython 的版本的依赖
‘cython’: [‘cython==0.23.4’]
}
)
在安装包时,pip 安装工具支持 extras 选项,该选项通过向包名称添加[extra-name]
后缀进行安装。对于上述示例,从本地源安装时,可以使用以下命令启用可选的 Cython 依
赖与编译器:
$ USE_CYTHON=1 pip install .[with-cython]