从另一个包导入Cython标头

时间:2016-04-22 14:38:46

标签: python cython python-import

我有一个名为A的包:

A/
  __init__.py
  _test.pyx

我有另一个名为B的软件包的来源:

B/
  __init__.py
  _wrapper.pxd
  _other.pxd
  _other.pyx

_wrapper.pxd包装了一个C库。我希望cimport

中的_wrapper.pxd A/_test.pyx

所以我在_test.pyx中执行此操作:

from B cimport _wrapper

我的setup.py看起来像这样:

ext_modules = cythonize([
           Extension("A._test", ["src/A/_test.pyx"], include_dirs=["/path/to/B", "."])])

当我编译时,我得到B.pxd not found,然后是一堆错误。

如何将另一个包中的cython模块导入我的包中?

1 个答案:

答案 0 :(得分:7)

简短回答

要从其他软件包中导入.pxd文件,您需要为软件包提供__init __。 pxd 文件。然后,您可以将包B视为cython包,而不必担心包含路径。

生殖

我试图像这样重现错误:

setup.py
  A/
    __init__.py
    _test.pyx
  B/
    __init__.py
    _wrapper.pxd
    _other.pxd
    _other.pyx
_wrapper.pxd
cdef inline foo():
    print("42")
_test.pyx
from B cimport _wrapper

cpdef bar():
    _wrapper.foo()
setup.py
from distutils.core import Extension, setup
from Cython.Build import cythonize

ext_modules = cythonize([
        Extension("A._test", ["A/_test.pyx"])])
setup(ext_modules=ext_modules)

它不适用于此错误:

A/_test.pyx: cannot find cimported module 'B'
Compiling A/_test.pyx because it changed.
[1/1] Cythonizing A/_test.pyx

Error compiling Cython file:
------------------------------------------------------------
...
from B cimport _wrapper
^
------------------------------------------------------------

A/_test.pyx:1:0: 'B.pxd' not found

Error compiling Cython file:
[...]

这应该是你所面对的。

如何解决此问题

对我来说,添加一个空的__init __。pxd文件解决了这个问题。我不需要指定包含路径或使用__init__.py并使用上面列出的文件。上面没有显示的所有文件都是空的。

$ touch B/__init__.pxd

setup.py
  A/
    __init__.py
    _test.pyx
  B/
    __init__.pxd
    _wrapper.pxd
    _other.pxd
    _other.pyx

$ python setup.py build_ext --inplace
$ ipython

In [1]: from A import _test

In [2]: _test.bar()
42

我希望这适合你。

替代

如果是一个选项,请考虑将_wrapper.pxd移动到A文件夹。 然后你可以直接使用:

cimport _wrapper

我想你想要保留包装结构,所以这只是为了完整起见。