我正在尝试了解循环导入问题,这里我有三个python文件,
py1.py
import py3
py3.test3()
def test1():
print 'test 1'
py2.py
import py1
py1.test1()
def test2():
print 'test 2'
py3.py
import py2
py2.test2()
def test3():
print 'test 2'
当我运行python py3.py
并得到这样的错误时,
Traceback (most recent call last):
File "py3.py", line 1, in <module>
import py2
File "/home/me/Desktop/hackerearth/cylic/py2.py", line 1, in <module>
import py1
File "/home/me/Desktop/hackerearth/cylic/py1.py", line 1, in <module>
import py3
File "/home/me/Desktop/hackerearth/cylic/py3.py", line 3, in <module>
py2.test2()
AttributeError: 'module' object has no attribute 'test2'
但是当我从py1.py文件中删除import py3
时,我得到的输出没有任何错误。任何人都解释我为什么会遇到这个错误。
答案 0 :(得分:6)
在Python中,文件以的形式执行它们被解析。在def
已“执行”之前,函数不存在。
你的问题是这样的:当你import
一个模块时,解析器停在该文件中的位置,并开始解析(执行)正在导入的新文件。
因此,当您运行python py3.py
时,它会开始解析文件。它到达import py2
,然后停止正在进行的操作以开始解析py2.py
,等等py1.py
。
当它到达import py3
时,再次开始削减它。但是,当它到达import py2
时,它意识到它已已导入py2
,并转到下一行。在这里,它会遇到py2.test2()
。但是,请记住,我们从未完成解析py2
,因此test2()
尚不存在。
按执行顺序:
# start at py3.py
import py2
# now in py2.py
import py1
# now in py1.py
import py3
# now in py3.py - this time being parsed as module
import py2 # this already happened, skip it.
py2.test2() # doesn't exist yet
如果您将print
语句添加到文件的最顶层,您将看到此行为。
真正的问题是你有全局可执行语句。相反,如果您包含典型的构造:
if __name__ == '__main__':
# First real executable statement goes here
然后,在模块完全导入之前,您永远不会尝试“做任何事情”。