我的项目具有以下目录结构:
.
├── Makefile
├── pxd
├── pyx
│ ├── Landscaping.pyx
│ ├── Shrubbing.pxd
│ └── Shrubbing.pyx
└── setup.py
但是,如果我将Shrubbing.pxd
移到pxd/
的任何其他地方,我会收到以下错误:
Error compiling Cython file:
------------------------------------------------------------
...
import pyx.Shrubbing
cimport Shrubbing
^
------------------------------------------------------------
pyx/Landscaping.pyx:2:8: 'Shrubbing.pxd' not found
Error compiling Cython file:
------------------------------------------------------------
...
import pyx.Shrubbing
cimport Shrubbing
cdef Shrubbing.Shrubbery sh
^
------------------------------------------------------------
这很奇怪,因为setup.py
我有:
from distutils.core import setup, Extension
from Cython.Build import cythonize
setup(ext_modules=cythonize([
Extension(
'pyx.Landscaping',
sources=["pyx/Landscaping.pyx"],
include_dirs=['pxd']), # <-- HERE
Extension('pyx.Shrubbing', sources=["pyx/Shrubbing.pyx"])
]))
清楚地指定Shrubbing.pxd
的新目录。
源文件都很短,但为了避免使这篇文章变得混乱,我只想发布一个链接到存储库:https://github.com/lobachevzky/landscaping
感谢您的帮助。
答案 0 :(得分:2)
include_dirs
用于C / C ++标头,而不是Cython pxd
文件。
一般情况下,最好将相关的pyx/pxd
文件保存在同一目录中,即Shrubbing.pyx和Shrubbing.pxd应位于同一目录中。
然后使用其他模块中的内容,通过扩展名中使用的名称包含__init__.pxd
和cimport
,例如pyx.Shrubbing
,就像使用Python一样模块。
如果在python中导入(不是cimport
),也应该包含__init__.py
。
在同一模块OTOH中使用时,.pxd
需要在该模块的运行时可用,这意味着将其包含在 Python 搜索路径中。
如果要将pxd文件组织到单独的目录中,请在模块目录中以符号方式链接它们,以使它们可供模块使用,dir包含__init__.pxd
或.py
文件。
由于Cython目前不支持相对导入,因此需要在从另一个目录导入时需要链接。
答案 1 :(得分:1)
严格地说,这个答案比你提出的具体问题更广泛。它更“如何在包之间共享pxd
定义”。
为了自己解决这个问题,我创建了一个cython_example回购。这并不令人满意,因为它使用旧的distutils
工具而不是setuptools
来阻止zip/egg
封装底层文件,但可能会在这里阐明一些内容。我正在积极寻找可以自动从egg
文件中提取代码的改进,以便setuptools
可以使用。
核心思想是使用os.path.dirname(from_package.__file__)
来添加到包含路径。请参阅setup.py文件。
<强>更新强>:
cython
email list提供了一个提示,即使用zip_unsafe
进行安装时使用setuptools
会使一切正常。请参阅updated working example和update I added至documentation。