我有一个具有深层嵌套模块层次结构的库,其结构如
src/
my_library/
__init__.py
my_module/
__init__.py
my_submodule.py
例如,一个人可以写from my_library.my_module.my_submodule import Foo
等等。
我有一个函数,它遍历文件树,发现所有python模块并将它们转换为传递到Extension
的{{1}}个对象,有效地对整个模块进行cython化。在构建它们之前检查它们(以字典形式)看起来像:
cythonize
然后将扩展列表传递到(Pdb) pp vars(e)
{'define_macros': [],
'depends': [],
'export_symbols': [],
'extra_compile_args': [],
'extra_link_args': [],
'extra_objects': [],
'include_dirs': [],
'language': None,
'libraries': [],
'library_dirs': [],
'name': 'my_library.my_module.my_submodule',
'optional': None,
'runtime_library_dirs': [],
'sources': ['src/my_library/my_module/my_submodule.c'],
'swig_opts': [],
'undef_macros': []}
的{{1}}参数。调用ext_modules
会产生一系列预期的编译,这很好。但是,文件会在编译之前写入镜像其位置的目录结构,因此例如最终会出现类似
setuptools.setup()
由于这种嵌套结构,我只能在安装目录位于我的setup.py install
中时导入顶级对象:
lib/python3.4/site-packages/
my_library.cpython-34m.so
my_library/
my_module.cpython-34m.so
my_module/
my_submodule.cpython-34m.so
似乎由于生成的文件被写入子目录而不是直接写入PYTHONPATH
文件夹,因此python解释器无法发现它们。我不太了解python扩展,但环顾四周我没有看到让python将它们放在扁平结构中而不是嵌套的方法,也不知道是否有办法让python发现{{1写入子目录的文件 - 可能是通过添加>>> import my_library
>>> my_library.foo()
'foo'
>>> import my_library.my_module
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named 'my_library.my_module'
个文件?
答案 0 :(得分:1)
看起来你“双重定义”my_library
:一次通过__init__.py
文件,一次通过cython代码。
解决方案是拥有一个“纯Python”模块层次结构,并在与Python模块发生任何冲突之外,将cython模块创建为该层次结构中的元素。
src/
my_library/
__init__.py
my_first_cython_module.pyx
my_module/
__init__.py
my_submodule.py
other_cython_module.pyx
这样,您可以执行import my_library.my_module
等。对于Cython模块,导入my_library.my_first_cython_module
等。
您可以通过从__init__.py
文件中导入cython代码来保留当前的导入名称:
from my_library.my_first_cython_module import foo