【问题标题】:Python circular import, `from lib import module` vs `import lib.module`Python 循环导入,`from lib import module` vs `import lib.module`
【发布时间】:2014-04-19 07:23:39
【问题描述】:

我有两个 python 模块,a.pyb.py,它们都在 lib/ 相对于当前目录。假设每个模块都需要另一个模块的功能。

a.py:

import lib.b
...

b.py:

import lib.a
...

上面的例子适用于

PYTHONPATH=./lib python -c 'from lib import a, b'

但是,如果我将 a.pyb.py 中的导入分别切换为 from lib import bfrom lib import a,则上述 Python 命令将以 ImportError 终止。

有人能解释一下为什么会中断吗?我不想从ab 导入任何成员。 (在这种情况下,我将从一个未初始化的模块导入,正如下面提到的问题所指出的那样。)

参考:

  1. python circular imports once again (aka what's wrong with this design)

【问题讨论】:

  • -1 -- "works" 和 "breaks" 没有意义。请通过提供演示该行为的可运行示例来说明您的意思。此外,如果您遇到错误,您应该发布所有您获得的输出,如果您获得意外结果,您应该发布您获得的预期和实际结果。
  • +1:我可以重现该问题。 @Bakuriu:运行test_from_vs_import.py

标签: python python-2.7 import


【解决方案1】:

由于似乎没有直接的方法来解决循环导入问题,因此我采用了一种解决方法。

在我的实际用例中,模块a导入模块b只是为了调用函数b.fn,所以我决定将fn放在第三个模块c中,并改为导入c

c.py

def fn():
  ...

b.py

from lib import a
from lib import c
...
# Explicitly assign `fn` into this module.
fn = c.fn

(上面也可以使用from lib.c import fn,但我更喜欢显式版本。)

a.py

from lib import c
...

这样,ab 之间的循环导入就消失了,任何导入b 的附加模块都可以直接使用b.fn

【讨论】:

    【解决方案2】:

    在你的 lib 文件夹中有一个 __init__.py 文件? 如果是,您有两种可能性:

    1) __init__.py 为空,可以使用 from lib import a,b

    a.foo b.bar

    2) 在你的 __init__.py 中有指令 import a,b 在这种情况下你可以写

    将 lib.a 导入为 将 lib.b 导入为 b

    希望对你有帮助

    【讨论】:

    • lib/__init_py 为空。我可以在这个文件中导入ab,但这对循环导入问题没有帮助。此外,我想避免将lib/ 下的每个包都添加到lib/__init__.py
    猜你喜欢
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    • 2012-10-22
    相关资源
    最近更新 更多