python - 我应该如何构建包含 Cython 代码的 Python 包

标签 python packaging cython

我想制作一个 Python 包,其中包含一些 Cython代码。我的 Cython 代码运行良好。但是,现在我想知道如何最好地打包它。

对于大多数只想安装软件包的人,我想包含 Cython 创建的 .c 文件,并安排 setup.py 进行编译生成模块。那么用户不需要安装 Cython 来安装包。

但是对于可能想要修改包的人,我还想提供 Cython .pyx 文件,并且以某种方式还允许 setup.py使用 Cython 构建它们(因此那些用户需要安装 Cython)。

我应该如何构建包中的文件以适应这两种情况?

Cython documentation gives a little guidance .但它没有说明如何制作一个处理有/无 Cython 情况的单个 setup.py

最佳答案

我现在自己在 Python 包中完成了 simplerandom ( BitBucket repo - 编辑:现在 github )(我不认为这是一个流行的软件包,但这是学习 Cython 的好机会)。

这种方法依赖于这样一个事实,即使用 Cython.Distutils.build_ext 构建一个 .pyx 文件(至少对于 Cython 版本 0.14)似乎总是创建一个 .c 文件与源 .pyx 文件位于同一目录中。

这里是 setup.py 的精简版,我希望它能够显示要点:

from distutils.core import setup
from distutils.extension import Extension

try:
    from Cython.Distutils import build_ext
except ImportError:
    use_cython = False
else:
    use_cython = True

cmdclass = {}
ext_modules = []

if use_cython:
    ext_modules += [
        Extension("mypackage.mycythonmodule", ["cython/mycythonmodule.pyx"]),
    ]
    cmdclass.update({'build_ext': build_ext})
else:
    ext_modules += [
        Extension("mypackage.mycythonmodule", ["cython/mycythonmodule.c"]),
    ]

setup(
    name='mypackage',
    ...
    cmdclass=cmdclass,
    ext_modules=ext_modules,
    ...
)

我还编辑了 MANIFEST.in 以确保 mycythonmodule.c 包含在源代码分发中(使用 python setup.py 创建的源代码分发sdist):

...
recursive-include cython *
...

我没有将 mycythonmodule.c 提交到版本控制“主干”(或 Mercurial 的“默认”)。当我发布版本时,我需要记住首先执行 python setup.py build_ext,以确保 mycythonmodule.c 存在并且是最新的源代码分发。我还创建了一个发布分支,并将 C 文件提交到该分支。这样我就有了与该版本一起分发的 C 文件的历史记录。

关于python - 我应该如何构建包含 Cython 代码的 Python 包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4505747/

相关文章:

python - 如何获取 Bottle.py 动态路由的 URL?

Python 类似于 Tomcat 和另一个 Servlet 容器

python - 与函数相比,类方法的 cython 优化令人沮丧

python - 如何在Cython中根据Python版本有条件地声明代码?

python - 如何优化速度以计算 3D 阵列中沿 Z 轴的平均值? Cython 与 Numpy

python - Kubernetes Python Pod分析

python - 多个 python 装饰器

python - PyQt5:根据文档出现一个信号而不是两个

virtualenv - 如何将我的 python virtualenv 复制到另一台机器