模块可以周期性地相互导入,但有一个问题。在简单的情况下,它应该通过将import
语句移动到文件底部或不使用from
语法来工作。
这就是为什么它有效:
当你导入一个模块时,Python 首先检查sys.modules
. 如果它在那里,它只是从那里进口。如果它不存在,它会尝试以正常方式导入它;基本上,它会找到文件并运行其中的内容。
运行模块会填充模块的内容。例如,假设我们有这个模块,创造性地命名为example_opener
:
import webbrowser
def open_example():
webbrowser.open('http://www.example.com/')
一开始,模块是空的。然后 Python 执行:
import webbrowser
之后,该模块仅包含webbrowser
. 然后 Python 执行这个:
def open_example():
webbrowser.open('http://www.example.com/')
Python 创建open_example
. 现在模块包含webbrowser
和open_example
。
说webbrowser
包含此代码:
from example_opener import open_example
def open(url):
print url
先说example_opener
进口。执行此代码:
import webbrowser
webbrowser
尚未导入,因此 Python 执行以下内容webbrowser
:
from example_opener import open_example
example_opener
已导入,但尚未完全执行。Python 不在乎。Python 将模块从sys.modules
. 此时,example_opener
依然是空的。它还没有定义open_example
,甚至还没有完成导入webbrowser
。open_example
Python在中找不到example_opener
,所以它失败了。
如果我们open_example
从 endwebbrowser
和webbrowser
end导入example_opener
怎么办?Python 将从执行以下代码开始:
def open_example():
webbrowser.open('http://www.example.com/')
webbrowser
open_example
尚不存在,但在被调用之前无关紧要。现在example_opener
只包含open_example
. 然后执行:
import webbrowser
它还没有被导入,所以 Python 执行webbrowser
. 开始:
def open(url):
print url
它定义了open
. 然后它执行:
from example_opener import open_example
example_opener
在 中sys.modules
,所以它使用它。example_opener
包含open_example
,所以它成功了。Python 完成导入webbrowser
. 从. webbrowser
_ example_opener
这是 中的最后一件事example_opener
,所以example_opener
完成的导入也成功了。