【问题标题】:Packaging python with cython extension使用 cython 扩展打包 python
【发布时间】:2017-10-06 11:26:30
【问题描述】:

我正在尝试构建一个同时使用 python 和 cython 模块的包。我在构建和安装后处理导入的问题,我不确定如何从构建过程生成的.so 文件导入文件。

在构建之前我的文件夹结构是这样的

root/
├── c_integrate.c
├── c_integrate.pyx
├── cython_builder.py
├── __init__.py
├── integrator_class.py
├── integrator_modules
│   ├── cython_integrator.py
│   ├── __init__.py
│   ├── integrator.py
│   ├── numba_integrator.py
│   ├── numpy_integrator.py
│   ├── quadratic_error.png
│   ├── report3.txt
│   ├── report4.txt
│   └── report5.txt
├── report6.txt
├── setup.py
└── test
    ├── __init__.py
    └── test_integrator.py

使用python3.5 setup.py build 构建会在root 中提供这个新文件夹

root/build/
├── lib.linux-x86_64-3.5
│   ├── c_integrate.cpython-35m-x86_64-linux-gnu.so
│   ├── integrator_modules
│   │   ├── cython_integrator.py
│   │   ├── __init__.py
│   │   ├── integrator.py
│   │   ├── numba_integrator.py
│   │   └── numpy_integrator.py
│   └── test
│       ├── __init__.py
│       └── test_integrator.py

setup.py 文件如下所示

from setuptools import setup, Extension, find_packages
import numpy

setup(
    name = "integrator_package",
    author = "foo",
    packages = find_packages(),
    ext_modules = [Extension("c_integrate", ["c_integrate.c"])],
    include_dirs=[numpy.get_include()],
)

然后我的问题是:如何将函数的导入语句从 .so 文件写入位于 build 目录中的 rootcython_integratortest_integrator 中的 ìntegrator_class.py 中。附加到sys.path 似乎是一个我不太喜欢的快速而肮脏的解决方案。

编辑: 正如 cmets 中指出的那样,我尚未安装该软件包。这是因为我不知道写什么要从.so 文件中导入

【问题讨论】:

  • this 相关吗?
  • 似乎您没有像@DavidW 指出的那样安装您构建的软件包。发出pip install path/to/root/pip install --editable=path/to/root/ 以将构建的文件与python 结合。
  • 是的,我还没有安装它——但我的问题是,由于.so 文件被命名为特定于平台的文件,我不知道如何导入它。特别是因为lib.linux... 文件夹没有__init__.py 文件。另外:在我安装并尝试重命名 .so 文件并导入它之后,它会引发 SystemError: Parent module '' not loaded, cannot perform relative import

标签: python packages cython setuptools


【解决方案1】:

没有特定的顺序:

  1. 文件 setup.py 通常位于项目的根目录下。示例:

    library_name/
        __init__.py
        file1.py
    setup.py
    README
    
  2. 然后,构建目录出现在项目源代码旁边,而不是项目源代码中。

  3. 要在 Python 中导入文件 c_integrate.cpython-35m-x86_64-linux-gnu.so,只需导入“c_integrate”即可。其余的命名会自动处理,因为它只是平台信息。见PEP 3149

  4. 一个有效的模块是其中之一

    1. 带有modulename/__init__.py 文件的目录
    2. 一个名为modulename.py的文件
    3. 一个名为modulename.PLATFORMINFO.so的文件

    当然位于 Python 路径中。因此,编译的 Cython 模块不需要 __init__.py 文件。

    根据您的情况,将 Cython 代码移动到项目目录中,然后执行相对导入 import .c_integrate 或完整的 from integrator_modules import c_integrate,后者仅在您的软件包已安装时才有效 .

可以在我关于 Cython 模块 http://pdebuyl.be/blog/2017/cython-module.html987654322@的博客文章中找到其中一些信息

我相信这应该可以让你构建一个合适的包,如果没有,请在下面评论。

编辑:完成配置(见下面的 cmets),海报也

  1. 修复了 setup.py 文件中的模块路径,使其成为从 PYTHONPATH 开始的完整模块名称:Extension("integrator_package.integrator_modules.c_integrat‌​or", ["integrator_package/integrator_modules/c_integrator.c"] 而不是 Extension("c_integrate", ["c_integrate.c"])]
  2. Cythonize 模块,构建它并与同一个 Python 解释器一起使用。

进一步说明:setup.py 文件也可以对文件进行 cythonize。包含.pyx 文件而不是.c 文件作为源。

cythonize(Extension('integrator_package.integrator_modules.c_integrat‌​or',
          ["integrator_package/integrator_modules/c_integrator.pyx"],
          include_dirs=[numpy.get_include()]))

【讨论】:

  • 非常感谢您的回答!我对树进行了更改,因此看起来像您建议的那样。我现在在导入 cython 模块 ImportError: dynamic module does not define module export function (PyInit_c_integrator) 时遇到错误。安装文件将扩展构建为ext_modules = [Extension("integrator_package.integrator_modules.c_integrator", ["integrator_package/integrator_modules/c_integrator.c"]
  • 解决了来自this线程的答案。原来cython 是构建敏感的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多