我有一个带有以下行的Bottle Webserver模块:
from foobar.formtools import auto_process_form_insert
该foobar.formtools模块包含以下行:
foobar.formtools
from foobar.webserver import redirect, redirect_back
当然,两者都分别导致以下错误:
ImportError:无法导入名称auto_process_form_insert ImportError:无法导入名称重定向
难道仅仅是一个事实,在Python中,两个模块不能互相导入,并且所有模块的导入本质上必须是分层的,还是我做错了什么?另外,是否有一种解决方法,不能将所有这些好的功能都放在新模块中?
模块 可以 周期性地相互导入,但是有一个陷阱。在简单的情况下,它应该通过将import语句移到文件底部或不使用from语法来工作。
import
from
这是可行的原因:
导入模块时,Python首先检查sys.modules。如果在其中,则仅从那里导入。如果不存在,它将尝试以常规方式导入它;基本上,它会找到文件并在其中运行内容。
sys.modules
运行模块将填充模块的内容。例如,假设我们有这个模块,创造性地命名为example_opener:
example_opener
import webbrowser def open_example(): webbrowser.open('http://www.example.com/')
首先,该模块为空。然后Python执行:
import webbrowser
之后,该模块仅包含webbrowser。然后Python执行此操作:
webbrowser
def open_example(): webbrowser.open('http://www.example.com/')
Python创建open_example。现在,该模块包含webbrowser和open_example。
open_example
说webbrowser包含以下代码:
from example_opener import open_example def open(url): print url
说example_opener先进口。该代码被执行:
webbrowser尚未导入,因此Python执行以下内容webbrowser:
from example_opener import open_example
example_opener 有 被导入,但尚未完全执行。Python不在乎。Python将模块从中拉出sys.modules。此时,example_opener仍为空。它尚未定义open_example,甚至尚未完成导入webbrowser。Pythonopen_example在中找不到example_opener,因此失败。
如果我们进口open_example从结束webbrowser和webbrowser从结束example_opener?Python将通过执行以下代码开始:
webbrowser还不存在,但是直到open_example被调用都没有关系。现在example_opener仅包含open_example。然后执行:
它尚未被导入,因此Python执行webbrowser。开始:
def open(url): print url
它定义了open。然后执行:
open
example_opener在中sys.modules,因此它使用了它。example_opener包含open_example,因此成功。Python完成导入webbrowser。结束webbrowser从的导入example_opener。这是中的最后一件事example_opener,因此,example_opener完成的导入也很成功。