import in python 3,请解释输出

import in python 3, explain the output please

内容:

tutorials/maindir/
├── dir1
│   ├── file11.py
│   ├── file12.py
│   ├── __init__.py
│   └── __pycache__
│       ├── file11.cpython-36.pyc
│       └── __init__.cpython-36.pyc
├── dir2
│   ├── file21.py
│   ├── file22.py
│   └── __init__.py
├── file1.py
├── file2.py
├── __init__.py
└── __pycache__
    ├── file1.cpython-36.pyc
    └── __init__.cpython-36.pyc

现在我有一个代码给出了我没有得到的输出。

代码::

print("--main--", dir())
from tutorials.maindir import *
print("--main--", dir())

输出::

--main-- ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
tutorials
tutorials.maindir
tutorials.maindir.dir1
--main-- ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'dir1', 'tutorials']

我不明白为什么 dir1tutorials 会出现在 dir() 的输出中。

maindir.__init__.py 的代码:

print(__name__)
import tutorials.maindir.dir1.file11

编辑 1 ::

所以如果代码是:

print("--main--", dir())
import tutorials.maindir.dir1.file11
print("--main--", dir())

输出为:

--main-- ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
tutorials
tutorials.maindir
tutorials.maindir.dir1
--main-- ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'tutorials']

当您 运行 一个 import 时,您正在导致 __init__.py 到 运行。 [source]

If __all__ is not defined, the statement from sound.effects import * does not import all submodules from the package sound.effects into the current namespace; it only ensures that the package sound.effects has been imported (possibly running any initialization code in __init__.py) and then imports whatever names are defined in the package. This includes any names defined (and submodules explicitly loaded) by __init__.py. It also includes any submodules of the package that were explicitly loaded by previous import statements.

在你的情况下,这包括另一个 import:

import tutorials.maindir.dir1.file11

这导致某些东西绑定到本地名称空间:[source]

define a name or names in the local namespace for the scope where the import statement occurs.

更具体地说:

If the module being imported is not a top level module, then the name of the top level package that contains the module is bound in the local namespace as a reference to the top level package. The imported module must be accessed using its full qualified name rather than directly

所以在你的例子中,tutorials 是已经导入的顶级模块,dir1 是导入的包(通过父名称选择)。

最后 dir() 将会:[source]

Without arguments, return the list of names in the current local scope. With an argument, attempt to return a list of valid attributes for that object.

根据您的评论,顶级包和导入语句中定义的各个名称都绑定到本地名称空间,这就是它们出现的原因,但 maindir 不是顶级包或导入包,因此它没有出现。


编辑:和附加信息

首先,如果所有这些对您来说都非常有趣或相关,我建议您阅读一些技术文章:

  • PEP 420 -- 隐式命名空间包
  • PEP 302 -- 新导入挂钩
  • PEP 328 -- 导入:多行和 Absolute/Relative

这些 PEP 讨论了很多现代导入的工作原理和它的一些特殊和奇怪的部分,以及如何构建它来完成您在用例中需要它做的事情。


关于您的编辑问题:

When the name variable is of the form package.module, normally, the top-level package (the name up till the first dot) is returned, not the module named by name. However, when a non-empty fromlist argument is given, the module named by name is returned. [source]

因此对于您的基本长导入语句,它会将顶层模块放入命名空间。

If the list of identifiers is replaced by a star ('*'), all public names defined in the module are bound in the local namespace for the scope where the import statement occurs. [source]

import name 给你 name
import name.one 给你 name
import name.one.two 给你 name
from name import one给你一个
from name import one as two给你两个

现在回到你的例子:
from tutorials.maindir import * 将首先导入顶层模块。然后 __init__.py 将 运行 执行另一个导入。该导入将跳过顶层模块,因为它已经导入,并将向下移动到包,然后作为父项的名称导入,或者基本上是最右边的 . 它将向左移动一个术语并导入为那个名字。 [code].