循环导入AttributeError:' module'对象没有属性

时间:2014-03-26 03:20:36

标签: python

我正在尝试了解循环导入问题,这里我有三个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时,我得到的输出没有任何错误。任何人都解释我为什么会遇到这个错误。

1 个答案:

答案 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

然后,在模块完全导入之前,您永远不会尝试“做任何事情”。