Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
两个Python模块相互需要';s的内容-可以吗?_Python_Python Module - Fatal编程技术网

两个Python模块相互需要';s的内容-可以吗?

两个Python模块相互需要';s的内容-可以吗?,python,python-module,Python,Python Module,我有一个瓶子Web服务器模块,其行如下: from foobar.formtools import auto_process_form_insert 而foobar.formtools模块包含以下行: from foobar.webserver import redirect, redirect_back 当然,两者都会导致以下错误(分别): 导入错误:无法导入名称自动处理表单插入 ImportError:无法导入名称重定向 这仅仅是一个事实,在Python中,两个模块不能相互导入,所有模块

我有一个瓶子Web服务器模块,其行如下:

from foobar.formtools import auto_process_form_insert
foobar.formtools
模块包含以下行:

from foobar.webserver import redirect, redirect_back
当然,两者都会导致以下错误(分别):

导入错误:无法导入名称自动处理表单插入
ImportError:无法导入名称重定向

这仅仅是一个事实,在Python中,两个模块不能相互导入,所有模块导入本质上都必须是分层的,还是我做错了什么?或者,除了将所有这些漂亮的功能放在新模块中之外,还有其他解决方法吗?

模块可以周期性地相互导入,但有一个缺点。在简单的情况下,它应该通过将
import
语句移动到文件底部或不使用
from
语法来工作

这就是为什么这样做的原因:

导入模块时,Python首先检查
sys.modules
。如果它在那里,它只是从那里进口。如果它不在那里,它会尝试以正常的方式导入它;基本上,它会找到文件并运行其中的内容

运行模块会填充模块的内容。例如,假设我们有这个模块,创造性地命名为
example\u opener

import webbrowser

def open_example():
    webbrowser.open('http://www.example.com/')
from example_opener import open_example
开始时,模块为空。然后Python执行:

import webbrowser
import webbrowser
from example_opener import open_example
之后,模块仅包含
webbrowser
。然后Python执行以下操作:

def open_example():
    webbrowser.open('http://www.example.com/')
Python创建
open\u示例
。现在,模块包含
webbrowser
open\u示例

webbrowser
包含此代码:

from example_opener import open_example

def open(url):
    print url
def open_example():
    webbrowser.open('http://www.example.com/')
假设先导入
示例\u opener
。执行此代码:

import webbrowser
webbrowser
尚未导入,因此Python执行
webbrowser
的内容:

import webbrowser

def open_example():
    webbrowser.open('http://www.example.com/')
from example_opener import open_example
示例\u opener
已导入,但尚未完全执行。Python不在乎。Python将模块从
sys.modules
中拉出。此时,
example\u opener
仍然为空。它还没有定义
open\u示例
,甚至还没有完成导入
webbrowser
。Python在
example\u opener
中找不到
open\u example
,因此失败

如果我们从
webbrowser
的末尾导入
open\u示例
,从
example\u opener
的末尾导入
webbrowser
,会怎么样?Python将首先执行以下代码:

from example_opener import open_example

def open(url):
    print url
def open_example():
    webbrowser.open('http://www.example.com/')
webbrowser
尚不存在,但在调用
open\u示例之前,它并不重要。现在
example\u opener
只包含
open\u example
。然后执行:

import webbrowser
import webbrowser
from example_opener import open_example
它还没有被导入,所以Python执行
webbrowser
。它开始于:

def open(url):
    print url
它定义了
打开
。然后执行:

import webbrowser
import webbrowser
from example_opener import open_example

example\u opener
位于
sys.modules
中,因此它使用了它
example\u opener
包含
open\u example
,因此它成功了。Python完成导入
webbrowser
。这就结束了从
example\u opener
导入
webbrowser
。这是
example\u opener
中的最后一件事,因此导入
example\u opener
也会成功完成。

不要从中执行
。。。导入…
。只需导入…
并使用模块名引用其对象。

。这通常是我在django要做的事情,有时候你只需要循环导入。在底部或函数或方法范围内导入。@Codemonkey:我注意到您添加了可以避免使用来自的
。。。导入…
语法,但我在顶部的回答中已经提到了这一点:“在简单的情况下,它应该通过[…]不使用
from
语法来工作。”不过我认为这不会解决循环导入问题。@jdi:会的。在导入时,模块将是空的,但由于它没有尝试获取模块内部的任何内容(但),这并不重要。我想说,不特别建议将导入放在bottom或混合点。作为一般的经验法则。这也使得可维护性更容易,想象有人在底部看到导入,认为在那里很愚蠢,将它们移动到顶部,然后看着代码中断。如果您尝试在导入的第一个模块的模块范围内访问第二个模块的属性,则可能会出现相同的错误。例如,假设我从内部
bar.py
导入foo。我从内部
foo.py
导入条形图。假设
foo.py
首先得到处理
foo->import bar->import foo
,其中最终的
import foo
将引用部分实例化的
foo
模块。现在,如果在bar.py内部,在模块范围内,我做了类似于
bar_常量=max(100,foo.foo_常量)
的操作,它将失败,因为bar.py可以获得句柄的
foo
尚未实例化
foo_常量。
。正如我在回答中所解释的,模块可以相互导入,但如果需要这样做,您可能需要重新考虑您的设计。我认为这个解释更容易理解:另请参阅