循环导入

循环导入

什么是循环导入

# mod1.py 文件
print('from mod1.py')
from mod2 import x

y = 'mod1'

1:创建 mod2 的名称空间。

2:执行 mod2.py ,将执行产生的名字放入 mod2.py 的名称空间中。

3:在当前执行文件中拿到 mod2 的 x

# mod2.py 文件
print('from mod2.py')
from mod1 import y

x = 'mod2'

1:创建 mod1 的名称空间。

2:执行 mod1.py ,将执行产生的名字放入 mod1.py 的名称空间中。

3:在当前执行文件中拿到 mod1 的 y

# run.py
import mod1

1:创建mod1的名称空间

2:执行mod1.py,将执行产生的名字丢到mod1.py

3:在当前执行文件中拿到mod1

# 运行 run.py 文件后报错
# ImportError: cannot import name 'y'

解决方案

  • 方案一:
# mod1.py 文件 
print('from mod1.py')
y = 'mod1'  # 将 y 提前定义好

from mod2 import x
  • 方案二:
# mod1.py 文件
print('from mod1.py')

def func():
    from mod2 import x,func1
    print(x)
    func1()

y = 'mod1'
# mod2.py 文件
print('from mod2.py')

def func1():
    from mod1 import y
    print(y)

x = 'mod2'
# run.py 文件
import mod1
mod1.func()
# from mod1.py
# from mod2.py
# mod2
# mod1

模块查找顺序

1:先从内存中找

2:内置中找

3:环境变量中找(sys.path)

注意:一定要分清谁是执行文件,谁是被导入的模块。

内存中找

# mod.py 文件
def func():
    print('from mod func')
# run.py 文件
import time  # 运行之后立马将 mod.py 文件删除
time.sleep(10)  # 这时候因为文件还在执行,当源文件被删除后,内存中这个时候还存在。当代码执行结束后,再执行就会报错
mod.func()  
# 可以发现,文件被删除后,还能基础打印
# from mod func

在内置中找

# time.py 文件
print('from time.py')
# run.py 文件
import time
print(time)
# <module 'time' (built-in)>

环境变量中找

如果文件 mod.py 在 D/python 路径下,而执行文件在 D/python/bin 路径下,用普通的导入一定会出错,我们可以把 D/python 添加到环境变量中,防止出错。

# run.py 文件
import sys
sys.path.append(r'D/python')

import mod
mod.fun()

搜索路劲都是以执行文件为准

假设被导入的 mod.py 和 mod1.py 文件在 D/python/dir 的路径下,而执行文件在 D/python 的路径下。

# mod.py 文件
from dir import mod1
def func():
    print('from mod func')
    mod1.func1()
# mod1.py 文件
def func1():
	print('from mod1 func1')
# run.py 文件
from dir import mod
mod.func()
# from mod func
# from mod1 func1
千里之行,始于足下。
原文地址:https://www.cnblogs.com/jincoco/p/11210753.html