循环导入问题

循环导入问题

一、什么是循环导入

60循环导入问题-死循环.jpg?x-oss-process=style/watermark

# m1.py
"""
@author RansySun
@create 2019-08-15-15:45
"""
print("m1中正在导入m2")
from m2 import y

x = 'm1'
print("m1中y:", y)
  1. 创建m2的名称空间
  2. 执行m2.py,将执行产生的名字丢到m2.py
  3. 在当前执行文件中拿到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)
  1. 创建m1的名称空间
  2. 执行m1.py,将执行产生的名字丢到m1.py
  3. 在当前执行文件中拿到m1.x
# run.py
import m1
  1. 创建m1的名称空间
  2. 执行m1.py,将执行产生的名字丢到m1.py
  3. 在当前执行文件中拿到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'

分析原因:

  1. 首先运行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中导入类会产生循环导入问题

在当下的阶段,必将由程序员来主导,甚至比以往更甚。
原文地址:https://www.cnblogs.com/randysun/p/11360029.html