我有一个Bottle webserver模块,其中包含以下行:
from foobar.formtools import auto_process_form_insert
foobar.formtools
模块包含以下行:
from foobar.webserver import redirect, redirect_back
当然,两者都会导致以下错误:
ImportError:无法导入名称auto_process_form_insert
ImportError:无法导入名称重定向
这只是一个事实,在Python中,两个模块不能互相导入,所有模块导入必须是分层的,或者我做错了什么?或者,是否有一种解决方法,而不是将所有这些不错的功能放在新模块中?
答案 0 :(得分:59)
模块可以周期性地互相导入,但是有一个问题。在简单的情况下,它应该通过将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
。 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
的导入也会成功完成。
答案 1 :(得分:18)
不要from ... import ...
。只需执行import ...
并使用模块名称引用其对象。