一尘不染

两个Python模块需要彼此的内容-可以吗?

python

我有一个带有以下行的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中,两个模块不能互相导入,并且所有模块的导入本质上必须是分层的,还是我做错了什么?另外,是否有一种解决方法,不能将所有这些好的功能都放在新模块中?


阅读 130

收藏
2020-12-20

共1个答案

一尘不染

模块 可以 周期性地相互导入,但是有一个陷阱。在简单的情况下,它应该通过将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。现在,该模块包含webbrowseropen_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。Pythonopen_example在中找不到example_opener,因此失败。

如果我们进口open_example从结束webbrowserwebbrowser从结束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完成的导入也很成功。

2020-12-20