To better support introspection, modules should explicitly declare the names in their public API using the __all__ attribute. Setting __all__ to an empty list indicates that the module has no public API.
"""This is the example module.
This module does stuff.
"""
...
__all__ = ['a', 'b', 'c']
__all__ = [] # or might have some initial names
from .subpackage import (name1, name2, name3)
__all__.extend(['name1', 'name2', 'name3']) # or append 1-by-1 or +=
我甚至看到过一种稍微有点马虎的方法,尽管在某些情况下可以说更易于维护,它看起来是这样的:
__all__ = []
from .subpackage import *
from .subpackage import __all__ as _all
__all__.extend(_all)
del _all
# Core API
__all__ = ['name', 'name2', 'name3']
from .sub1 import name1
from .sub2 import name2, name3
try:
import optional_dependency
except ImportError:
# Let it be, it maybe issue a warning
pass
else:
from .opt_support import name4, name5
__all__ += ['name4', 'name5']
The public names defined by a module are determined by checking the module’s namespace for a variable named __all__; if defined, it must be a sequence of strings which are names defined or imported by that module.
Asequence支持迭代(for x in __all__)和使用整数索引(__all__[i])进行访问。所以它可以是一个列表,也可以是一个元组
没有使用} idiomatically represents a sequence of same kind of items but ^{} represents a sequence of different kind of items. 这也是由类型提示编码的,在
list
或tuple
的绑定理由However, ^{tuple[str, int, int]
内有一些list[str | int]
但位置字段因此,
list
更准确地表示“任意名称序列”政治公众人物8反复提到
__all__
是一个列表:从实用的角度来看,半动态地将元素添加到
__all__
有些常见。当您想要在顶层公开在包结构中深层定义的函数时,就会发生这种情况。使用列表更容易做到这一点有几个这样做的模块示例是numpy和pyserial。我强烈怀疑Django在某些地方也会这样做,但我对它还不够熟悉,无法确定
这个成语在
__init__.py
中看起来像这样:我甚至看到过一种稍微有点马虎的方法,尽管在某些情况下可以说更易于维护,它看起来是这样的:
显然,通过使用可变的
__all__
,可以大大简化这一过程。在事实发生后将其转换为元组或使用+=
将其“附加”到元组没有实质性的好处当您的API依赖于可选的外部包时,可变
__all__
的另一种有用方式是。在列表中启用或禁用名称比在元组中启用或禁用名称容易得多下面是一个模块示例,如果安装了名为
optional_dependency
的库,该模块将启用其他功能:报告说:
Asequence支持迭代(
for x in __all__
)和使用整数索引(__all__[i]
)进行访问。所以它可以是一个列表,也可以是一个元组相关问题 更多 >
编程相关推荐