模块可以周期性地相互导入,但有一个问题。在简单的情况下,它应该通过将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_examplePython在中找不到example_opener,所以它失败了。
如果我们open_example从 endwebbrowser和webbrowserend导入example_opener怎么办?Python 将从执行以下代码开始:
def open_example():
webbrowser.open('http://www.example.com/')
webbrowseropen_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完成的导入也成功了。