我在__init__.py文件中看到__all__。它做什么?
当前回答
PEP8中定义如下:
全局变量名称(我们希望这些变量只在一个模块中使用。)这些约定与函数的约定大致相同。为通过from M import*使用而设计的模块应该使用__all__机制来防止导出全局变量,或者使用旧的惯例,在这些全局变量前加下划线(您可能希望这样做,以表明这些全局变量是“模块非公共的”)。
PEP8为Python代码提供了编码约定,该Python代码包含Python主发行版中的标准库。你越是遵循这一点,你就越接近最初的意图。
其他回答
它还改变了pydoc将显示的内容:
模块1.py
a = "A"
b = "B"
c = "C"
模块2.py
__all__ = ['a', 'b']
a = "A"
b = "B"
c = "C"
$pydoc模块1
Help on module module1: NAME module1 FILE module1.py DATA a = 'A' b = 'B' c = 'C'
$pydoc模块2
Help on module module2: NAME module2 FILE module2.py DATA __all__ = ['a', 'b'] a = 'A' b = 'B'
我在我的所有模块中声明__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>导入。
它是该模块的公共对象列表,由import*解释。它覆盖了隐藏以下划线开头的所有内容的默认设置。
__all__从<模块>导入中自定义**和来自<package>import*。
模块是要导入的.py文件。
包是包含__init__.py文件的目录。包通常包含模块。
模块
""" cheese.py - an example module """
__all__ = ['swiss', 'cheddar']
swiss = 4.99
cheddar = 3.99
gouda = 10.99
__all__让人类了解模块的“公共”特性。[@AaronHall]而且,pydoc认出了他们。[@Longpoke]
从模块导入*
看看swiss和cheddar是如何被引入本地命名空间的,而不是gouda:
>>> from cheese import *
>>> swiss, cheddar
(4.99, 3.99)
>>> gouda
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'gouda' is not defined
如果没有__all__,任何符号(不以下划线开头)都将可用。
不带*的进口不受__all影响__
导入模块
>>> import cheese
>>> cheese.swiss, cheese.cheddar, cheese.gouda
(4.99, 3.99, 10.99)
从模块导入名称
>>> from cheese import swiss, cheddar, gouda
>>> swiss, cheddar, gouda
(4.99, 3.99, 10.99)
将模块导入为localname
>>> import cheese as ch
>>> ch.swiss, ch.cheddar, ch.gouda
(4.99, 3.99, 10.99)
包装
在包__all__的__init__.py文件中,有一个字符串列表,其中包含公共模块或其他对象的名称。这些功能可用于通配符导入。与模块一样,__all__在从包中导入通配符时自定义*。[@MartinStettner]
以下是Python MySQL连接器__init__.py的摘录:
__all__ = [
'MySQLConnection', 'Connect', 'custom_error_exception',
# Some useful constants
'FieldType', 'FieldFlag', 'ClientFlag', 'CharacterSet', 'RefreshOption',
'HAVE_CEXT',
# Error handling
'Error', 'Warning',
...etc...
]
包的默认情况是星号,不带__all__,这很复杂,因为明显的行为代价很高:使用文件系统搜索包中的所有模块。相反,在我阅读文档时,只导入__init__.py中定义的对象:
如果未定义__all__,sound.effects import*中的语句不会将sound.eeffects包中的所有子模块导入当前命名空间;它只确保包sound.effects已经导入(可能在__init__.py中运行任何初始化代码),然后导入包中定义的任何名称。这包括__init__.py定义的任何名称(以及显式加载的子模块)。它还包括以前的import语句显式加载包的任何子模块。
最后,随处可见的堆积如山的答案、教授和漫画家,这是一个受人尊敬的传统,这是对一开始就提出问题的指责:
通配符导入。。。应该避免,因为它们会混淆读者和许多自动化工具。
[PEP 8,@ToolmakerSteve]
PEP8中定义如下:
全局变量名称(我们希望这些变量只在一个模块中使用。)这些约定与函数的约定大致相同。为通过from M import*使用而设计的模块应该使用__all__机制来防止导出全局变量,或者使用旧的惯例,在这些全局变量前加下划线(您可能希望这样做,以表明这些全局变量是“模块非公共的”)。
PEP8为Python代码提供了编码约定,该Python代码包含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