将Python模块移入子文件夹后出现的部分初始化问题
Python模块重构后循环导入导致的部分初始化错误解决
原模块结构与正常运行状态
原模块结构:
mymod ├── config.py └── __init__.py
文件代码:
# __init__.py import mymod.config mymod.config.foo() # config.py def foo(): print('here')
执行命令 python3 -c "import mymod",正常输出 here。
重构后的结构与报错情况
重构后目录结构:
mymod ├── core │ ├── config.py │ └── __init__.py └── __init__.py
修改后代码:
# 根目录__init__.py import mymod.core # core/__init__.py import mymod.core.config mymod.core.config.foo() # core/config.py(无改动) def foo(): print('here')
执行 python3 -c "import mymod" 时触发错误:
$ python3 -c "import mymod" Traceback (most recent call last): File "<string>", line 1, in <module> File "/home/gsgx/code/mymod/__init__.py", line 1, in <module> import mymod.core File "/home/gsgx/code/mymod/core/__init__.py", line 3, in <module> mymod.core.config.foo() AttributeError: partially initialized module 'mymod' has no attribute 'core' (most likely due to a circular import)
原因:导入mymod.core的过程中,mymod模块尚未完成初始化,此时尝试通过mymod.core层级访问子模块,会触发属性不存在的错误。
无需大量重构的解决方案
方案1:延迟初始化代码执行
将core模块的初始化逻辑封装为函数,在根模块导入完成后再调用:
# 根目录__init__.py import mymod.core # 导入完成后再执行初始化 mymod.core.init() # core/__init__.py import mymod.core.config def init(): mymod.core.config.foo()
方案2:使用相对导入访问子模块
修改core/init.py的导入方式为相对导入,避免通过未完全初始化的mymod模块访问:
# core/__init__.py from . import config config.foo()
方案3:将子模块绑定到本地命名空间
通过import ... as语法直接将config模块绑定到本地变量,绕过mymod.core层级访问:
# core/__init__.py import mymod.core.config as config config.foo()
以上三种方案均只需修改少量代码,无需大规模重构原有导入逻辑。
内容的提问来源于stack exchange,提问作者gsgx
相关产品推荐
相关产品推荐

