我在__init__.py文件中看到__all__。它做什么?
当前回答
我只是准确地补充一下:
所有其他答案均涉及模块。最初的问题明确提到__init__.py文件中的__all__,所以这是关于python包的。
通常,__all__仅在使用import语句的from xxx import*变体时生效。这适用于软件包和模块。
其他答案中解释了模块的行为。这里详细描述了包的确切行为。
简而言之,包级别的__all__与模块的作用大致相同,只是它处理包中的模块(与在模块中指定名称相反)。因此__all__指定了当我们使用from package import*时应加载并导入到当前命名空间中的所有模块。
最大的区别是,当您在包的__init__.py中省略__all__的声明时,包import*中的语句根本不会导入任何内容(除了文档中解释的例外,请参见上面的链接)。
另一方面,如果在模块中省略__all__,则“星号导入”将导入模块中定义的所有名称(不以下划线开头)。
其他回答
链接到,但此处未明确提及,正是使用__all__的时间。这是一个字符串列表,用于定义当在模块上使用from<module>import*时,将导出模块中的符号。
例如,foo.py中的以下代码显式导出符号bar和baz:
__all__ = ['bar', 'baz']
waz = 5
bar = 10
def baz(): return 'baz'
然后可以按如下方式导入这些符号:
from foo import *
print(bar)
print(baz)
# The following will trigger an exception, as "waz" is not exported by the module
print(waz)
如果上面的__all__被注释掉,则该代码将执行到完成,因为import*的默认行为是从给定的命名空间中导入所有不以下划线开头的符号。
参考:https://docs.python.org/tutorial/modules.html#importing-从一个包
注意:__all__仅影响from<module>import*行为。__all__中未提及的成员仍可从模块外部访问,并可通过<module>import<member>导入。
我只是准确地补充一下:
所有其他答案均涉及模块。最初的问题明确提到__init__.py文件中的__all__,所以这是关于python包的。
通常,__all__仅在使用import语句的from xxx import*变体时生效。这适用于软件包和模块。
其他答案中解释了模块的行为。这里详细描述了包的确切行为。
简而言之,包级别的__all__与模块的作用大致相同,只是它处理包中的模块(与在模块中指定名称相反)。因此__all__指定了当我们使用from package import*时应加载并导入到当前命名空间中的所有模块。
最大的区别是,当您在包的__init__.py中省略__all__的声明时,包import*中的语句根本不会导入任何内容(除了文档中解释的例外,请参见上面的链接)。
另一方面,如果在模块中省略__all__,则“星号导入”将导入模块中定义的所有名称(不以下划线开头)。
它是该模块的公共对象列表,由import*解释。它覆盖了隐藏以下划线开头的所有内容的默认设置。
PEP8中定义如下:
全局变量名称(我们希望这些变量只在一个模块中使用。)这些约定与函数的约定大致相同。为通过from M import*使用而设计的模块应该使用__all__机制来防止导出全局变量,或者使用旧的惯例,在这些全局变量前加下划线(您可能希望这样做,以表明这些全局变量是“模块非公共的”)。
PEP8为Python代码提供了编码约定,该Python代码包含Python主发行版中的标准库。你越是遵循这一点,你就越接近最初的意图。
简短的回答
__all__影响<module>import*语句。
答案很长
考虑以下示例:
foo
├── bar.py
└── __init__.py
在foo/__init__.py中:
(隐式)如果我们不定义__all__,那么from foo import*将只导入foo/__init__.py中定义的名称。(显式)如果我们定义__all__=[],那么from foo import*将不导入任何内容。(显式)如果我们定义__all__=[<name1>,…],那么from foo import*将只导入这些名称。
注意,在隐式情况下,python不会导入以_开头的名称。但是,您可以使用__all__强制导入此类名称。
您可以在此处查看Python文档。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- Printf与std::字符串?
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if