我有三个问题,但有关系,我没有得到如何将它们分开。我发现了很多关于这些问题的信息,例如submodule extension,hierarchy,关于empty __init__.py file以及如何cythonize multiple pyx files。但是当我一起尝试时,我无法让它们发挥作用。
我已经准备好small repo一起思考问题的代码示例。我甚至检查了一些使用cython的projects listed的代码,但仍然没有得到如何同时做三件事。
在一个项目中(所有文件都是 pyx (以及 pxd ifneedbe)),带有 __ init __。pyx ,其中包括所有文件它们,当有一个 __ init __。py 文件,然后导入它不会加载“ .so ”但是空的init。
而不是准备包含模块所有元素的 __ init __。py 。像:
cythonize(['factory.pyx', 'version.pyx'])
生成的“ .so ”导入引发异常:
>>> import barfoo
(...)
ImportError: dynamic module does not define init function (PyInit_barfoo)
如果有必要在 __ init __。py 中写一些东西,那么它与上一个问题有关。
事实上,这是主要问题。 singleton.pyx 是子模块的一部分,假设 utils 可以从模块中的其他元素中使用。
对于示例,在 setup.py 中添加了一个子模块(简称为 subm )作为另一个扩展。我放置的时间早于主要的(我不知道这是否确实有任何区别,我没有看到它)。
>>> import barfoo
>>> import barfoo.subm
(...)
ImportError: No module named 'barfoo.subm'
另外,这些食谱有效,但我不能。当“ py ”和“ pyx ”文件混合使用时,“ __ init __。py ”似乎是必要的。这些示例解释了如何使用多个文件进行cython化,但不包括导入的最后一个关键点。并且子模块没有完成如何从一个地方或另一个地方导入它们(导入子模块时导入子模块,或者指定它们时可选导入)。
答案 0 :(得分:2)
昨晚我看到了你的问题,根据wiki做了一个简单的例子。但这个问题很快被删除了。
以下是示例:https://github.com/justou/cython_package_demo
确保C编译器和python环境的设置正确,通过运行编译pyx文件:
python setup.py build_ext --inplace
用法与python包相同:
from dvedit.filters import flip, inverse, reverse
flip.show() # print: In flip call Core function
inverse.show() # print: In inverse call Core function
reverse.show() # print: In reverse call Core function
BTW,无需创建__init__.pyx
,您可以在__init__.py
文件中执行ext_module导入
答案 1 :(得分:2)
感谢oz1和DavidW的评论,我得到了solution。是的,这三件事情汇集在一起。
首先导入 cythonize 然后 setup ,当调用 cythonize(find_pyx())时,结果将是 distutils.extension.Extension 对象的列表。
from setuptools import setup, find_packages
from Cython.Build import cythonize
必须在 cython 之前导入setuptools ,然后 cythionize()的结果将是 setuptools.extension的列表。可以传递给 setup()调用的扩展对象。
所有带有includes的 __ init __。pyx 文件已被删除,每个 .pxy 文件都会生成自己的 .so 二进制文件。
主模块和子模块将存在,只要它们的目录包含 __ init __。py 文件,就像纯python代码一样。
在我已链接的示例中,文件 barfoo / __ init __。py 不为空,因为我希望 import barfoo 提供对 version()或 Factory()。然后,这个 __ init __。py 就像普通的纯Python那样导入它们。
类似于子模块及其自己的 __ init __。py 文件。在此示例中, import barfoo 将从.factory导入工厂执行,他将从barfoo.subm导入栏调用,然后 > subm 将可用。
但如果子模块未以此辅助方式导入,则用户可以通过 import barfoo.subm 等调用访问它。