模块 可以 周期性地相互导入,但是有一个陷阱。在简单的情况下,它应该通过将
import语句移到文件底部或不使用
from语法来工作。
这是可行的原因:
导入模块时,Python首先检查
sys.modules。如果在其中,则仅从那里导入。如果不存在,它将尝试以常规方式导入它;基本上,它会找到文件并在其中运行内容。
运行模块将填充模块的内容。例如,假设我们有这个模块,创造性地命名为
example_opener:
import webbrowserdef 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_exampledef 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。Python
open_example在中找不到
example_opener,因此失败。
如果我们进口
open_example从结束
webbrowser和
webbrowser从结束
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完成的导入也很成功。



