为什么在导入 A.B.C 时 python 将 'A' 放入全局命名空间

Why does python put 'A' in global namespace when I import A.B.C

我正在阅读 import 如何在 python 中工作。

当我这样做时:

import A.B.C
  1. A、A.B、A.B.C放在sys.modules中。预期。
  2. A 的 __init__、A.B 的 __init__ 被执行。预期。

但这里有一个惊喜:当我打印 globals() 时,只有 A 被放入命名空间,而 'A.B.C' 没有。我希望 'A.B.C' 在全局命名空间中。

这意味着,我可以访问 A 的 __init__ 中定义的 A.x。

为什么import是这样实现的?

B 和 C 可以通过 A 到达。

例如

import A.B.C
print(A.B.C)

如果您希望 B 和 C 直接出现在您当前的命名空间中,请执行

from A import B
from A.B import C

print(B, C)

只有 objects/names 被放入全局命名空间。 A.B.C 不是有效名称。

在你上面的例子中,对象是 A 的模块对象,它的名字是 A .

在这种特殊情况下,如果您这样做 -

dir(A)

你会在其中看到 B ,这意味着它是模块对象 A 的一个属性。如果你这样做 -

hasattr(A,'B')

会 return 正确。

同样,如果您这样做 - dir(A.B),您将能够在其中看到 C,并且 CA.B 的属性。


一个非常简单的例子来说明这一点 -

我的目录结构 -

shared/
      __init__.py
      pkg/
         __init__.py
         b.py

然后在代码中我做 -

>>> import shared.pkg.b
>>> dir(shared)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'pkg']
>>> hasattr(shared,'pkg')
True
>>>
>>> dir(shared.pkg)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'b']
>>> hasattr(shared.pkg,'b')
True