Python无法导入嵌套层次结构中生成的扩展

时间:2017-07-17 02:54:57

标签: python cython setuptools

我有一个具有深层嵌套模块层次结构的库,其结构如

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' 个文件?

1 个答案:

答案 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