Python 为什么“所有”在包中的工作方式与在模块中的工作方式不同?
import语句的Python文档包含以下内容: 通过检查模块名称空间中名为Python 为什么“所有”在包中的工作方式与在模块中的工作方式不同?,python,Python,import语句的Python文档包含以下内容: 通过检查模块名称空间中名为\uuuuu all\uuuuuu的变量来确定模块定义的公共名称;如果已定义,则它必须是由该模块定义或导入的名称组成的字符串序列 模块的Python文档包含看似矛盾的语句: 如果包的\uuuuu init\uuuuuuuupy.py代码定义了名为\uuuuuuu all\uuuuuuuuuuuu的列表,则当遇到来自包导入*的时,它被视为应导入的模块名称列表 然后给出了一个示例,其中一个\uuuuu init\uuuuuu
\uuuuu all\uuuuuu
的变量来确定模块定义的公共名称;如果已定义,则它必须是由该模块定义或导入的名称组成的字符串序列
模块的Python文档包含看似矛盾的语句:
如果包的\uuuuu init\uuuuuuuupy.py
代码定义了名为\uuuuuuu all\uuuuuuuuuuuu
的列表,则当遇到来自包导入*的时,它被视为应导入的模块名称列表
然后给出了一个示例,其中一个\uuuuu init\uuuuuuuuy.py
文件不导入任何内容,并简单地将\uuuuuuuuuuuuuuuuuuu
定义为该包中模块的一些名称
我已经测试了两种使用\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;事实上,一个人可以在相同的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuu
值内进行混合和匹配
例如,考虑目录结构
foopkg/
__init__.py
foo.py
其中\uuuu init\uuuu.py
包含
# Note no imports
def bar():
print("BAR")
__all__ = ["bar", "foo"]
注意:我知道不应该在\uuuu init\uuuuu.py
文件中定义函数。我这样做只是为了说明,同一个\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
可以导出当前名称空间中存在的名称和不存在的名称
运行以下代码,似乎自动导入foo模块:
>>> from foopkg import *
>>> dir()
[..., 'bar', 'foo']
为什么\uuuuuuuuuuuuuuuuuuuuu
属性有这种奇怪的双重行为
这些文档似乎真的不清楚它应该如何使用,只是在我链接的每个地方提到了它的两面中的一个。我理解其总体目的是显式设置通配符导入的名称,但我对附加的、看似自动导入的行为感到困惑。这只是一个神奇的快捷方式,可以避免将导入也写出来吗?更新:M import*的实际上是如何工作的
foopkg文件夹的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
中的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
为什么会自动导入foo您可以在此处看到:
最重要的是看一下cpython实现:
它基本上是通过\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
循环,并尝试导入中的每个元素
这就是为什么它会自动导入foo并实现白名单的原因。文档有点难解析,因为它没有提到包通常也有模块的行为,包括它们的\uuuuuuuu all\uuuuu
属性。包的行为必然是模块行为的超集,因为包与模块不同,可以有子包和子模块。就最终用户而言,与该特性无关的行为在两者之间是相同的
python文档有时可能是最低限度的。他们懒得提那件事
Package\uuuuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
模块支持包\uuuu init\uuuu.py
的所有功能,但不能有子包或子模块
不言而喻,把一个名字称为一个子模块,它必须被导入,因此是显而易见的,但不是真正的双重标准。我不明白为什么你认为这些陈述是矛盾的。foo.py
的内容是什么?导入后的foo
和bar
的类型是什么?@markransem可能是言过其实了;我的意思是,它们各自对\uuuuuuuuuuuuuu
的定义不同。foo.py
的内容不重要;导入后,foo
的类型为
,因此foo.py
中的任何内容都可以通过点符号访问bar
当然是类型
。它们是在不同类型的对象中定义的不同变量。他们的目的是不同的,所以根本没有矛盾all@MadPhysicist如果可以,请在回答中详细说明。我看不出在目的上有什么不同,只是在行为上。包和模块是不同的。从用户的角度来看,它们的行为在很大程度上是相似的,但它们不是一回事。模块只有属性。他们可以参考其他模块,但不能有子模块。这个虚构的foopkg.py
模块的理论内容是什么?i、 e.foo
在foopkg.py
中指的是什么?我理解\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。这只是你如何构造你的包/模块。当您说fromfoopgg import foo
foopgg可以是foopgg.py或foopgg(其中包含\uuu init\uuuu.py
)。对于自动导入问题,我发现当您删除\uuuu init\uuuuuuupy
foo
中的\uuuuuuuuuuuuuu
时,将不会导入。因此,我猜python如何处理import*
就是在\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
设置后,以某种方式逐个导入。我以你为榜样。我的问题是:为什么uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。“自动导入功能只是一种快捷方式,还是有更深层次的含义可以解释它?”克里斯。没有双重行为。包中的行为必然是模块中行为的超集。模块没有子模块。@C