构建 Cython 代码

原文: http://docs.cython.org/en/latest/src/quickstart/build.html

与 Python 不同,Cython 代码必须编译。这发生在两个阶段:

  • .pyx文件由 Cython 编译为.c文件,它含有 Python 扩展模块的代码。
  • .c文件由 C 编译器编译为.so文件(或 Windows 上的.pyd),可直接被import引入到 一个Python会话中. Distutils 或 setuptools 负责这部分。虽然 Cython 可以在某些情况下为你调用它们。

要完全理解 Cython + distutils / setuptools 构建过程,可能需要阅读更多关于分发 Python 模块的内容。

有几种方法可以构建 Cython 代码:

  • 写一个 distutils / setuptools setup.py。这是正常和推荐的方式。
  • 使用 Pyximport,导入 Cython .pyx文件就像它们是.py文件一样(使用 distutils 在后台编译和构建)。这种方法比编写setup.py更容易,但不是很灵活。因此,如果您需要某些编译选项,则需要编写setup.py
  • 手动运行cython命令行工具程序来将.pyx文件编译生成.c文件,然后手动将.c文件编译成适合从 Python 导入的共享库或 DLL。(这些手动步骤主要用于调试和实验。)
  • 使用 [Jupyter] 笔记本或 [Sage] 笔记本,两者都允许 Cython 代码内联。这是开始编写 Cython 代码并运行它的最简单方法。

目前,使用 distutils 或 setuptools 是构建和分发 Cython 文件的最常用方式。其他方法在参考手册的 源文件和编译 部分中有更详细的描述。

使用 distutils 构建 一个Cython 模块

想象一下文件hello.pyx中的一个简单的“hello world”脚本:

  1. def say_hello_to(name):
  2. print("Hello %s!" % name)

以下是相应的setup.py脚本:

  1. from distutils.core import setup
  2. from Cython.Build import cythonize
  3. setup(name='Hello world app',
  4. ext_modules=cythonize("hello.pyx"))

要构建,请运行python setup.py build_ext --inplace。然后只需启动一个 Python 会话并执行from hello import say_hello_to并根据需要使用导入的函数。

如果您使用 setuptools 而不是 distutils,则需要注意,运行python setup.py install时的默认操作是创建一个压缩的egg文件,当您尝试从依赖包中使用它们时,这些文件无法与pxd文件一起用于pxd文件。为防止这种情况,请在setup()的参数中包含zip_safe=False

使用Jupyter笔记本来构建

Cython 可以通过 Web 浏览器通过 Jupyter 笔记本方便地和交互式地使用。要安装 Jupyter 笔记本,例如进入 virtualenv,使用 pip:

  1. (venv)$ pip install jupyter
  2. (venv)$ jupyter notebook

要启用对 Cython 编译的支持,请按照 安装指南 中的说明安装 Cython,并从 Jupyter 笔记本中加载Cython扩展:

  1. %load_ext Cython

然后,使用%%cython标记为单元格添加前缀以进行编译:

  1. %%cython
  2. cdef int a = 0
  3. for i in range(10):
  4. a += i
  5. print(a)

您可以通过传递--annotate选项来显示 Cython 的代码分析:

  1. %%cython --annotate
  2. ...

../../_img/jupyter.png

有关%%cython魔法参数的更多信息,请参阅 使用 Jupyter 笔记本 进行编译。

使用 Sage 笔记本

../../_img/sage.png

对于 Sage 数学发行版的用户,Sage 笔记本允许通过在单元格顶部键入%cython并进行评估来透明地编辑和编译 Cython 代码。导入到运行会话中的 Cython 单元格中定义的变量和函数。

[Jupyter] https://jupyter.org/