【Cython】基本编译及调试方法
本文介绍两种常用的Cython代码编译方法以及调试方法
编译
手动编译(推荐)
本文推荐使用手动编译的方式,因为pyximport实时编译的方式不适用于同时包含pyx文件和pyd文件的情况。
只有一个pyx文件的情况
- 创建一个.pyd文件
example.pyx,其中包含以下内容:
# example.pyx
def fibonacci(n):cdef int icdef double a = 0.0, b = 1.0for i in range(n):a, b = a + b, aprint('a = ', a)return a
- 创建一个名为
setup.py的文件,其中包含以下内容:
# setup.py
from distutils.core import setup
from Cython.Build import cythonizesetup(ext_modules=cythonize("example.pyx", language_level=3))
这里example.pyx和setup.py在同一个文件夹下
- 打开终端,进入
setup.py所在的目录,然后运行以下命令:
python setup.py build_ext --inplace
该命令将编译 example.pyx 文件并生成对应的扩展模块。--inplace 参数表示将生成的文件放在当前目录中。
编译成功结果如下:

目录结构如下所示:

- 创建一个 Python 文件调用生成的模块:
import exampleexample.fibonacci(10)
输出为:

这个例子中,我们定义了一个 fibonacci 函数,然后在 setup.py 文件中使用 cythonize 函数对其进行编译。build_ext 参数告诉 distutils 命令构建扩展模块。在这个例子中,我们将编译后的文件生成到当前目录中,可以通过 import 语句导入并使用。
同时包含pyx文件和c文件的情况
如果你的Cython项目同时包含.pyx文件和.c文件,你需要确保你的编译器能够同时编译这两种类型的文件。为了完成这项工作,你可以使用setup.py文件来编译整个项目。
下面是一个示例setup.py文件:
from distutils.core import setup, Extension
from Cython.Build import cythonizeext_modules = [Extension("my_module", sources=["my_module.pyx", "my_c_file.c"]),
]setup(name="my_module",ext_modules=cythonize(ext_modules)
)
在这个示例中,我们创建了一个Extension对象,它将my_module.pyx和my_c_file.c这两个文件合并成一个模块。然后,我们使用cythonize函数将Extension对象转换为一个Cython扩展模块,然后将这个模块添加到setup函数中。
一旦你有了这个setup.py文件,你可以通过运行以下命令来编译你的项目:
python setup.py build_ext --inplace
这将会在当前目录下生成一个名为my_module.so的共享库文件(在Windows系统上是一个名为my_module.pyd的动态链接库文件),它包含了my_module.pyx和my_c_file.c这两个文件的编译结果。
同时包含pyx文件和pyd文件的情况
.pyd文件类似c语言中的.h头文件,主要用来做一些声明。如果你的Cython项目同时包含.pyx文件和.pyd文件,你需要使用Extension对象来将这些文件组合在一起,并使用cythonize函数来将Extension对象转换为一个Cython扩展模块。然后,你可以使用setup函数来编译整个项目。
下面是一个示例setup.py文件:
from distutils.core import setup, Extension
from Cython.Build import cythonizeext_modules = [Extension("my_module", sources=["my_module.pyx", "my_module.pyd"]),
]setup(name="my_module",ext_modules=cythonize(ext_modules)
)
在这个示例中,我们创建了一个Extension对象,它将my_module.pyx和my_module.pyd这两个文件合并成一个模块。然后,我们使用cythonize函数将Extension对象转换为一个Cython扩展模块,然后将这个模块添加到setup函数中。
一旦你有了这个setup.py文件,你可以通过运行以下命令来编译你的项目:
python setup.py build_ext --inplace
这将会在当前目录下生成一个名为my_module.so的共享库文件(在Windows系统上是一个名为my_module.pyd的动态链接库文件),它包含了my_module.pyx和my_module.pyd这两个文件的编译结果。
pyximport实时编译(有时不适用)
在开发过程中,pyximport要比手动编译方便,但是同时包含.pyx文件和.pyd文件时,编译一直不成功。这里就不推荐使用了,只介绍实现步骤:
- 假设我们有.pyd文件
example.pyx,其中包含以下内容:
# example.pyx
def fibonacci(n):cdef int icdef double a = 0.0, b = 1.0for i in range(n):a, b = a + b, aprint('a = ', a)return a
- 此时不需要手动编译,可以使用
pyximport直接在Python代码中调用这个fibonacci方法:
import pyximportpyximport.install(language_level=3)from example import fibonacci
print(fibonacci(10))
在这个示例中,我们首先导入了pyximport模块,并调用了它的install方法,这会设置Python解释器以实时编译Cython代码。然后,我们导入了example模块,并调用了使用它的fibonacci函数。
调试
这里介绍打印的方式调试,具体做法就是在.pyx文件中编写print()语句,需要注意以下几点:
- 修改打印语句后,要重新编译
- 指针syn的值的获取方法是
syn[0] - 在
with nogil:里的打印要加with gil:
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
