这个设置.py:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
extensions = (
Extension('myext', ['myext/__init__.py',
'myext/algorithms/__init__.py',
'myext/algorithms/dumb.py',
'myext/algorithms/combine.py'])
)
setup(
name='myext',
ext_modules=cythonize(extensions)
)
没有预期的效果。我希望它生成一个 myext.so
,它确实如此;但是当我通过
python -m myext.so
我得到:
ValueError: Attempted relative import in non-package
由于 myext
试图引用 .algorithms
。
知道如何让它工作吗?
最佳答案
首先,我应该注意到它是 impossible使用 Cython 编译带有子包的单个 .so
文件。所以如果你想要子包,你将不得不生成多个 .so
文件,因为每个 .so
只能代表一个模块。
其次,您似乎无法编译多个 Cython/Python 文件(我专门使用 Cython 语言)并将它们链接到一个模块中。
我尝试将多个 Cython 文件编译成单个 .so
各种方式,包括 distutils
和手动编译,但它总是无法导入运行时。
将已编译的 Cython 文件与其他库甚至其他 C 文件链接起来似乎没问题,但是在将两个已编译的 Cython 文件链接在一起时出现问题,结果不是正确的 Python 扩展。
我能看到的唯一解决方案是将所有内容编译为单个 Cython 文件。在我的例子中,我编辑了我的 setup.py
以生成一个 .pyx
文件,该文件又 include
每个 。 pyx
文件在我的源目录中:
includesContents = ""
for f in os.listdir("src-dir"):
if f.endswith(".pyx"):
includesContents += "include \"" + f + "\"\n"
includesFile = open("src/extension-name.pyx", "w")
includesFile.write(includesContents)
includesFile.close()
然后我就编译extension-name.pyx
。当然,这会破坏增量和并行编译,并且您最终可能会遇到额外的命名冲突,因为所有内容都被粘贴到同一个文件中。从好的方面来说,您不必编写任何 .pyd
文件。
我当然不会称这是一种更好的构建方法,但如果所有东西都必须在一个扩展模块中,这是我能看到的唯一方法。
关于python - 将多个子模块折叠为一个 Cython 扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30157363/