python循环导入
比如有如下目录结构:
1 | root.py |
root.py:
1 | from A.a import class_a |
a.py:
1 | from B.b import class_b |
b.py:
1 | from A.a import class_a |
此时运行 root.py 会发生报错:
ImportError: cannot import name ‘class_a’ from partially initialized module ‘A.a’ (most likely due to a circular import)
我们来解析一下运行过程:
- 执行 root.py 的
from A.a import class_a
,发现需要导入模块 a - 一个空的字典会被创建,对应 a 的 globals
- a.py 中的代码会被执行,当执行到
from B.b import class_b
时,发现需要导入模块 b - 一个空的字典会被创建,对应 b 的 globals
- b.py 中的代码会被执行,当执行到
from A.a import class_a
时,发现需要导入模块 a,但此时已经有 a 的 globals 了,所以直接访问字典里的 class_a,但由于 a 的 globals 还是空的,即没有 class_a,所以抛出异常。
总结:循环导入的根本原因就是在导入的时候, b 需要访问 a 的变量 class_a,而 class_a 没有初始化完成。
解决方法:
- 在导入的时候,让 b 不要访问 a 的变量
- class_a 初始化完成后,才让 b 访问 a 中的变量
方法一
import 整个模块,而不是 import 模块中的变量。
root.py:
1 | import A.a |
a.py:
1 | import B.b |
b.py:
1 | import A.a |
首先编译 a,编译过程中发现需要编译 b,编译 b 完成后,编译 a 剩下的部分。
方法二
把导入放在后面,或者把导入放在语句块中。
root.py:
1 | from A.a import class_a |
a.py:
1 | class class_a: |
b.py:
1 | class class_b: |