Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么“所有”在包中的工作方式与在模块中的工作方式不同?_Python - Fatal编程技术网

Python 为什么“所有”在包中的工作方式与在模块中的工作方式不同?

Python 为什么“所有”在包中的工作方式与在模块中的工作方式不同?,python,Python,import语句的Python文档包含以下内容: 通过检查模块名称空间中名为\uuuuu all\uuuuuu的变量来确定模块定义的公共名称;如果已定义,则它必须是由该模块定义或导入的名称组成的字符串序列 模块的Python文档包含看似矛盾的语句: 如果包的\uuuuu init\uuuuuuuupy.py代码定义了名为\uuuuuuu all\uuuuuuuuuuuu的列表,则当遇到来自包导入*的时,它被视为应导入的模块名称列表 然后给出了一个示例,其中一个\uuuuu init\uuuuuu

import语句的Python文档包含以下内容:

通过检查模块名称空间中名为
\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。这只是你如何构造你的包/模块。当您说from
    foopgg import foo
    foopgg可以是foopgg.py或foopgg(其中包含
    \uuu init\uuuu.py
    )。对于自动导入问题,我发现当您删除
    \uuuu init\uuuuuuupy
    foo
    中的
    \uuuuuuuuuuuuuu
    时,将不会导入。因此,我猜python如何处理
    import*
    就是在
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    设置后,以某种方式逐个导入
    。我以你为榜样。我的问题是:
    为什么uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。“自动导入功能只是一种快捷方式,还是有更深层次的含义可以解释它?”克里斯。没有双重行为。包中的行为必然是模块中行为的超集。模块没有子模块。@C