如何将模块添加至sys.modules解决子模块非相对导入报错问题
解决方案
方案1:运行时动态添加模块搜索路径(无侵入,最常用)
在你的项目入口代码(比如code/file.py,或者测试用例的启动文件)最开头加入以下代码,把子模块的根目录加入Python的模块搜索路径即可:
import sys from pathlib import Path # 计算submodule目录的绝对路径 VENDOR_SUBMODULE_ROOT = Path(__file__).parent.parent / "vendor" / "submodule" sys.path.insert(0, str(VENDOR_SUBMODULE_ROOT))
如果担心子模块的包名和其他依赖冲突,可以把insert(0)改为append(),降低子模块包的搜索优先级
后续不管是你导入package_2.beta,还是beta内导入package_1都可以正常识别,完全不需要修改子模块内的任何代码。
方案2:使用.pth文件(适合本地开发/CI固定环境)
在你使用的Python环境的site-packages目录下新建名为vendor_submodule.pth的文件,写入submodule目录的绝对路径即可:
/你的项目完整路径/root/vendor/submodule
Python启动时会自动把该路径加入搜索路径,无需修改任何业务代码。
方案3:打包配置声明(适合需要打包分发的项目)
如果你的项目使用setuptools打包,可以在pyproject.toml里加入如下配置,打包时会自动处理路径映射:
[tool.setuptools.package_dir] "" = "vendor/submodule"
补充说明:如果是Python 3.3+版本,原生支持命名空间包,就算包目录下没有
__init__.py也可以正常识别导入。如果使用的是更低的Python版本,可以直接在CI拉取子模块的步骤之后加一行自动创建空__init__.py的命令,不需要维护fork版本:touch vendor/submodule/package_1/__init__.py vendor/submodule/package_2/__init__.py直接加到CI执行脚本里即可,每次拉完代码自动执行,完全不影响原子模块的仓库内容。
内容的提问来源于stack exchange,提问作者aronchick
相关产品推荐
相关产品推荐

