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

Hub*_*bro 54 python python-module

我有一个Bottle webserver模块,其中包含以下行:

from foobar.formtools import auto_process_form_insert
Run Code Online (Sandbox Code Playgroud)

foobar.formtools模块包含以下行:

from foobar.webserver import redirect, redirect_back
Run Code Online (Sandbox Code Playgroud)

当然,两者都会导致以下错误:

ImportError:无法导入名称auto_process_form_insert
ImportError:无法导入名称重定向

事实上,在Python中,两个模块不能互相导入,并且所有模块导入必须是分层的,或者我做错了什么?或者,是否有一种解决方法是将所有这些不错的功能放在新模块中?

ick*_*fay 65

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

这就是为什么有效:

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

运行模块会填充模块的内容.例如,假设我们有这个模块,创造性地命名为example_opener:

import webbrowser

def open_example():
    webbrowser.open('http://www.example.com/')
Run Code Online (Sandbox Code Playgroud)

一开始,模块为空.然后Python执行:

import webbrowser
Run Code Online (Sandbox Code Playgroud)

之后,模块只包含webbrowser.然后Python执行:

def open_example():
    webbrowser.open('http://www.example.com/')
Run Code Online (Sandbox Code Playgroud)

Python创建open_example.现在该模块包含webbrowseropen_example.

webbrowser包含这个代码:

from example_opener import open_example

def open(url):
    print url
Run Code Online (Sandbox Code Playgroud)

example_opener先导入.执行此代码:

import webbrowser
Run Code Online (Sandbox Code Playgroud)

webbrowser尚未导入,因此Python执行以下内容webbrowser:

from example_opener import open_example
Run Code Online (Sandbox Code Playgroud)

example_opener 被导入,但尚未完全执行.Python并不关心.Python将模块拉出来sys.modules.此时,example_opener仍然是空的.它还没有定义open_example,甚至没有完成导入webbrowser.Python不能找到open_exampleexample_opener,所以它失败.

如果我们进口open_example从结束webbrowserwebbrowser从结束example_opener?Python将从执行此代码开始:

def open_example():
    webbrowser.open('http://www.example.com/')
Run Code Online (Sandbox Code Playgroud)

webbrowser还不存在,但直到open_example被调用才无所谓.现在example_opener只包含open_example.然后它执行:

import webbrowser
Run Code Online (Sandbox Code Playgroud)

它还没有导入,所以Python执行webbrowser.开始:

def open(url):
    print url
Run Code Online (Sandbox Code Playgroud)

它定义了open.然后它执行:

from example_opener import open_example
Run Code Online (Sandbox Code Playgroud)

example_opener是的sys.modules,所以它使用它.example_opener包含open_example,所以它成功了.Python完成导入webbrowser.这就是webbrowser从中导入的结论example_opener.这是最后一件事example_opener,因此example_opener成品的导入也是成功的.

  • 很好的故障.这通常是我在django所要做的,有时你只需要循环导入.在底部或在函数或方法范围内导入. (2认同)

pyr*_*ade 21

不要这样做from ... import ....只需import ...使用模块名称引用其对象即可.

  • @jdi:会的.在导入时,模块将是空的,但由于它没有尝试进入它内部的任何东西,所以它并不重要. (6认同)
  • 我想说,不建议特别将进口放在整个进口的底部或混合点。作为一般经验法则。 (5认同)
  • 这也使可维护性变得更加容易,想象一下有人看到底部的导入,认为它很愚蠢,将它们移到顶部并观察代码中断。 (2认同)