循环导入问题
一、什么是循环导入
# m1.py
"""
@author RansySun
@create 2019-08-15-15:45
"""
print("m1中正在导入m2")
from m2 import y
x = 'm1'
print("m1中y:", y)
- 创建m2的名称空间
- 执行m2.py,将执行产生的名字丢到m2.py
- 在当前执行文件中拿到m2.y
# m2.py
"""
@author RansySun
@create 2019-08-15-15:45
"""
print("m2中正在导入m1")
from m1 import x
y = 'm2'
print("打印m2中引用的x:", x)
- 创建m1的名称空间
- 执行m1.py,将执行产生的名字丢到m1.py
- 在当前执行文件中拿到m1.x
# run.py
import m1
- 创建m1的名称空间
- 执行m1.py,将执行产生的名字丢到m1.py
- 在当前执行文件中拿到m1
m1中正在导入m2
m2中正在导入m1
m1中正在导入m2
Traceback (most recent call last):
ImportError: cannot import name 'y' from 'm2' ( 模块循坏导入问题m2.py)
Traceback (most recent call last):
File "G:/python学习/03 模块循坏导入问题/m1.py", line 7, in <module>
from m2 import y
File "G:python学习/03 模块循坏导入问题m2.py", line 6, in <module>
from m1 import x
File "G:python学习 3 模块循坏导入问题m1.py", line 7, in <module>
from m2 import y
ImportError: cannot import name 'y'
分析原因:
- 首先运行run.py—>import m1,开始导入m1并运行其内部代码--->打印内容m1中正在导入m2--->执行from m2 import y 开始导入m2并运行其内部代码---->打印内容m2中正在导入m1 --->执行from m1 import x,由于m1已经被导入过了,所以不会重新导入,所以直接去m1中拿x然而此时x,并没有存在于m1中(x这句话还没有执行到),而是模块之间循环调用,所以会报错
二、解决方案
我们可以使用函数定义阶段只识别语法的特性解决循环导入的问题,我们也可以从本质上解决循环导入的问题,但是最好的解决方法就是不要出现死循环
2.1方案一
# m1
print("m1中正在导入m2")
x = 'm1'
from m2 import y
print("m1中y:", y)
print("m2中正在导入m1")
y = 'm2'
from m1 import x
print("打印m2中引用的x:", x)
结果:
m1中正在导入m2
m2中正在导入m1
已经找到!
m1中正在导入m2
m1中y: m2
已经找到!2
打印m2中引用的x: m1
m1中y: m2
分析:先运行m1 —>打印m1中正在导入m2—>m2中找x-->打印m2中正在导入m1, 接着打印已经找到!-->之后回到m1中继续运行--->打印m1中正在导入m2--->接着打印m1中y: m2—->之后会回到m2中执行剩下的代码--->执行到from m1 import x-->到m1中找到继续回到m2中---->接着打印已经找到!2--->打印打印m2中引用的x: m1-->回到m1中继续执行余下的代码
2.1 方案二
# m1
print("m1中正在导入m2")
x = 'm1'
def func1():
from m2 import y
print("m1中y:", y)
# m2
print("m2中正在导入m1")
y = 'm2'
def func2():
print("已经找到func2!")
from m1 import x
print("已经找到!2")
print("打印m2中引用的x:", x)
结果:
m1中正在导入m2
m2中正在导入m1
m1中y: m2
注:在django中的model.py中导入类会产生循环导入问题