Cython相对cimport无法工作 报超出主包相对导入错误
问题原因
该报错不是Cython的bug,属于配置疏漏。
Cython判定相对导入合法性的核心依据是Extension中声明的完整模块全限定名,和文件物理存放路径、include_dirs参数没有直接关系。你当前配置中将两个扩展模块声明为根级的landscaping、shrubbing,在Cython的解析逻辑中两个模块没有同包从属关系,因此会抛出relative cimport beyond main package is not allowed错误。include_dirs参数仅用于指定.pxd声明文件的搜索路径,不会改变模块的包层级归属,因此调整该参数无法解决问题。
修复方案
按照以下步骤调整配置即可正常使用相对导入:
- 在
src目录下新建空文件__init__.py,将src标记为正式Python包,Cython识别包结构需要该标记文件。 - 修改
setup.py中的Extension配置,将模块名调整为和包层级匹配的全限定名,同时修正include_dirs路径:
# setup.py import sys sys.argv = ["setup.py", "build_ext", "--inplace"] from setuptools import setup, Extension from Cython.Build import cythonize ext_modules = [ Extension('src.landscaping', ['src/landscaping.pyx']), Extension('src.shrubbing', ['src/shrubbing.pyx']), ] setup( ext_modules=cythonize(ext_modules), include_dirs=['./src'], )
- 编译完成后,在根目录的
main.py中按包路径导入模块即可运行:
# main.py from src import landscaping if __name__ == "__main__": landscaping.main()
如果你不希望导入时带
src.前缀,可以直接将pyx、pxd文件移动到项目根目录,去掉导入语句中的相对导入点即可;也可以通过setuptools的package_dir参数将src目录映射为根包,此时Extension的模块名不需要加src.前缀,相对导入同样可以正常生效。
内容的提问来源于stack exchange,提问作者William Hou
相关产品推荐
相关产品推荐

