【问题标题】:Why do these two Python imports work differently?为什么这两个 Python 导入的工作方式不同?
【发布时间】:2012-04-20 19:43:04
【问题描述】:

假设如下代码结构:

#### 1/hhh/__init__.py: empty

#### 1/hhh/foo/__init__.py:
from hhh.foo.baz import *

#### 1/hhh/foo/bar.py:
xyzzy = 4

#### 1/hhh/foo/baz.py:
import hhh.foo.bar as bar
qux = bar.xyzzy + 10

我在1/ 中运行python 并执行import hhh.foo.baz。它失败了:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "hhh/foo/__init__.py", line 1, in <module>
    from hhh.foo.baz import *
  File "hhh/foo/baz.py", line 1, in <module>
    import hhh.foo.bar as bar
AttributeError: 'module' object has no attribute 'foo'

现在我将baz.py 替换为:

# 1/hhh/foo/baz.py:
from hhh.foo.bar import xyzzy
qux = xyzzy + 10

再做一次import hhh.foo.baz。现在它可以工作了,虽然我加载的是同一个模块,只是绑定了一个不同的名称。

这是否意味着import modulefrom module import name 之间的区别不仅仅是标识符?这里到底发生了什么?

(我知道我可以使用相对导入来解决所有这些问题,但我仍然想了解其中的机制。另外,我不喜欢相对导入,PEP 8 也不喜欢。)

【问题讨论】:

    标签: python import module package


    【解决方案1】:

    当您编写from hhh.foo.bar import xyzzy 时,Python 解释器将尝试从模块hhh.foo.bar 加载xyzzy。但是如果你写import hhh.foo.bar as bar,它会首先尝试在hhh.foo模块中找到bar。所以它评估hhh.foo,做from hhh.foo.baz import * hhh.foo.baz 尝试评估 hhh.foohhh.foo 尝试评估 hhh.foo.baz,循环导入,异常。

    【讨论】:

      【解决方案2】:

      1/hhh/foo/__init__.py 中,您需要将__all__ 列表设置为您要导出的名称。即__all__ = ["xyzzy"]

      【讨论】:

        【解决方案3】:

        为什么要从 hhh.foo 中的 hhh.foo.bar 导入? import bar 应该足够了。

        【讨论】:

          猜你喜欢
          • 2015-10-27
          • 2010-10-06
          • 2021-08-30
          • 2019-11-08
          • 1970-01-01
          • 1970-01-01
          • 2019-08-18
          • 1970-01-01
          • 2022-01-26
          相关资源
          最近更新 更多