【问题标题】:Why does from pkg import * end up importing a module even if __all__ is not defined?为什么即使 __all__ 没有定义,from pkg import * 最终也会导入一个模块?
【发布时间】:2017-02-23 01:10:33
【问题描述】:

我以这种方式创建了一个包pkg

$ tree
.
└── pkg
    ├── foo.py
    └── __init__.py

1 directory, 2 files
susam@debian1:~/so$ cat pkg/__init__.py
susam@debian1:~/so$ cat pkg/foo.py
print('executing module foo ...')

def bar():
    print('bar')

以下所有 Python shell sn-ps 均来自单个交互式 与 Python 解释器的会话。我已将它们分成多个 块之间添加我自己的评论。

这是我的 Python 版本。

Python 3.4.2 (default, Oct  8 2014, 10:45:20)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

以下导入不会导入foo,因为__all__ 不是 在__init__.py 中定义。

>>> from pkg import *
>>> foo.bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined
>>>

上述行为已在 Python 教程中描述 https://docs.python.org/3/tutorial/modules.html#importing-from-a-package.

如果__all__没有定义,语句from sound.effects import * 不会将包 sound.effects 中的所有子模块导入 当前命名空间;它只确保包sound.effects 有 已导入(可能在 __init__.py) 然后导入在 包。

以下仅导入 bar()。它不导入foo

>>> from pkg.foo import bar
executing module foo ...
>>> bar()
bar
>>> foo.bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined

但奇怪的是在上一次导入之后,下面的导入结束了 导入foo,即使__all__ 未在__init__.py 中定义。

>>> from pkg import *
>>> foo.bar()
bar

为什么会这样?

【问题讨论】:

    标签: python package python-import python-3.6


    【解决方案1】:

    根据您引用的 Python 文档,当您使用 from pkg import * 时,您只会导入模块 foo 以及 __init__.py,而不是 foo 的函数。

    我怀疑您提供的最后一个代码 sn-p 有效,因为您已经直接从 foo 导入 bar() 并在严格导入 bar 函数后重新导入 foo 建立 foo 和 @ 之间的连接987654329@.

    您在指定__all__ 时是否遇到同样的问题?

    【讨论】:

    • from pkg import * 不应导入模块 foo,除非定义了 __all__。如果指定了__all__,我不会遇到同样的问题。我很想知道为什么from pkg import * 的第一次出现与文档一致,即不导入foo,但from pkg import * 的第二次出现违反了文档并导入foo
    【解决方案2】:

    foo 已经在 pkg 命名空间中导入为 pkg.foo 当您执行 from pkg.foo import bar 时。因此,当您将所有名称从 pkg 命名空间导入到当前范围时,您也导入了 foo。见:

    >>> import pkg
    >>> dir(pkg)
    ['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']
    >>> from pkg.foo import bar
    executing module foo ...
    >>> dir(pkg)
    ['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'foo']
    

    (我在 python 2 上,但逻辑是一样的)

    【讨论】:

      猜你喜欢
      • 2018-09-21
      • 1970-01-01
      • 2018-03-11
      • 1970-01-01
      • 2016-06-03
      • 2012-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多