在python 3中导入,请解释输出

Sha*_*ngh 6 python python-import python-3.x

内容:

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
Run Code Online (Sandbox Code Playgroud)

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

代码::

print("--main--", dir())
from tutorials.maindir import *
print("--main--", dir())
Run Code Online (Sandbox Code Playgroud)

输出::

--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']
Run Code Online (Sandbox Code Playgroud)

我不知道为什么dir1tutorials并且在dir()的输出中。

maindir.__init__.py 的代码:

print(__name__)
import tutorials.maindir.dir1.file11
Run Code Online (Sandbox Code Playgroud)

编辑1 ::

因此,如果代码是:

print("--main--", dir())
import tutorials.maindir.dir1.file11
print("--main--", dir())
Run Code Online (Sandbox Code Playgroud)

输出为:

--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']
Run Code Online (Sandbox Code Playgroud)

MyN*_*leb 8

当您运行时,import会导致__init__.py运行。[ 来源 ]

如果未定义__all__,则sound.effects import *的语句不会将包sound.effects中的所有子模块导入当前名称空间;它仅确保已导入包sound.effects(可能在__init__.py中运行任何初始化代码),然后导入包中定义的任何名称。这包括__init__.py定义的任何名称(以及明确加载的子模块)。它还包括以前的import语句显式加载的包的所有子模块。

就您而言,这包括另一个import

import tutorials.maindir.dir1.file11
Run Code Online (Sandbox Code Playgroud)

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

在本地名称空间中为发生import语句的作用域定义一个或多个名称。

更具体地说:

如果要导入的模块不是顶级模块,则包含该模块的顶级包的名称绑定在本地名称空间中,作为对顶级包的引用。导入的模块必须使用其完整限定名称而不是直接访问

因此,在您的情况下,tutorials是已经导入的顶层模块,并且dir1是导入的程序包(通过选择其父名称)。

然后最后dir()要去:[ 来源 ]

不带参数的情况下,返回当前本地范围内的名称列表。使用参数,尝试返回该对象的有效属性列表。

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


编辑:及附加信息

首先,如果您对所有这些都非常感兴趣或相关,那么我建议对一些事情进行一些技术性阅读:

这些PEP讨论了很多现代导入的工作方式以及其中的一些特殊和怪异部分,以及如何形成它以执行您在用例中需要做的事情。


关于您的编辑问题:

name变量的形式为package.module时,通常返回顶级包(名称直到第一个点),而不是按名称命名的模块。但是,当给出非空的fromlist参数时,将返回name命名模块。[ 来源 ]

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

如果标识符列表由星号(*)代替,则模块中定义的所有公共名称都将在本地名称空间中绑定到导入语句发生的范围。[ 来源 ]

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

现在回到您的示例:
from tutorials.maindir import *首先将导入顶层模块。然后__init__.py将运行另一个导入。该导入将跳过顶层模块,因为该模块已经被导入,并且将向下移动到包中,然后以父级的名称进行导入,或者实际上最右边的模块.将向左移动一个术语并以该名称导入。[ 代码 ]。