为什么Python在使用from imports时对循环导入更严格?
我知道Python不鼓励任何可能导致循环导入的情况。但我想了解Python的内部结构,为什么在循环导入情况下,从导入看起来比正常导入更不宽容 例如,此代码编译:为什么Python在使用from imports时对循环导入更严格?,python,python-import,python-internals,Python,Python Import,Python Internals,我知道Python不鼓励任何可能导致循环导入的情况。但我想了解Python的内部结构,为什么在循环导入情况下,从导入看起来比正常导入更不宽容 例如,此代码编译: # main.py import CommonUtil # commonutil.py import util class CommonUtil: # some code that uses util.Util pass # util.py import commonutil class Util: # so
# main.py
import CommonUtil
# commonutil.py
import util
class CommonUtil:
# some code that uses util.Util
pass
# util.py
import commonutil
class Util:
# some code that uses commonutil.CommonUtil
pass
但该代码不:
# main.py
import CommonUtil
# commonutil.py
import util
class CommonUtil:
# some code that uses util.Util
pass
# util.py
from commonutil import CommonUtil
class Util:
# some code that uses CommonUtil
pass
Traceback (most recent call last):
File "main.py", line 1, in <module>
import CommonUtil
File "commonutil.py", line 1, in <module>
import util
File "util.py", line 1, in <module>
from commonutil import CommonUtil
ImportError: cannot import name CommonUtil
#main.py
导入CommonUtil
#commonutil.py
导入util
类CommonUtil:
#一些使用util.util的代码
通过
#util.py
从commonutil导入commonutil
类Util:
#一些使用CommonUtil的代码
通过
回溯(最近一次呼叫最后一次):
文件“main.py”,第1行,在
导入CommonUtil
文件“commonutil.py”,第1行,在
导入util
文件“util.py”,第1行,在
从commonutil导入commonutil
ImportError:无法导入名称CommonUtil
只要在所有导入完成之前不尝试使用相关类,就不会出现编译器错误。但是当你尝试做一些别名时,它就失败了。有人能解释一下Python内部发生了什么,只有在使用from import时才会导致这个错误?第二,有没有简单的方法?(除了明显的“将共享代码拉到第三个模块”之外,我可能会这样做。)模块是从上到下执行的。当第一次看到导入时,当前模块的执行将暂停,以便可以导入其他模块。当另一个模块尝试导入第一个模块时,它会获取对当前部分执行的模块的引用。由于在导入其他模块后找到的代码尚未执行,因此其中包含的任何名称都不可能存在 main.py a、 派克 b、 派克 解决方法是在导入模块的执行完成之前,不要访问该模块中的名称。有关发生的情况的解释,请参阅
我假设您启动了main.py文件。Python将首先尝试加载
commonutil
。它将创建一个模块对象,并在遇到它们的定义时开始用类、函数和全局变量填充它。第一条语句是import,因此现在python创建util
模块并开始填充它。公共模块存在,但为空。在第一个版本中,加载时不访问任何commonutil对象,因此一切正常。在第二个示例中,您尝试获取commonutil中目前不存在的特定变量。如果您在第一个版本中使用了类似于f(commonutil.commonutil)
的东西,它也会崩溃。在您的第一个示例中,import commonutil.commonutil
应该引发一个ImportError
,因为commonutil
不是一个模块。您是对的。我的意思是import commonutil
和import util
——我已经做了这些更改。
import a
var1 = 'foo'
import b
var2 = 'bar'
import a
print a.var1 # works
print a.var2 # fails