在 Python 中,__all__ 是一个特殊的模块级变量,用于定义模块的公共接口。具体来说,它的作用是:
1. 控制 from module import * 的行为
- 当在模块中定义了
__all__时,from your_module import *只会导入__all__列表中指定的名称。 - 如果没有定义
__all__,import *会默认导入所有不以下划线开头的全局名称(如函数、类、变量等)。
2. 明确公开的 API
- 它作为模块的“白名单”,明确告诉用户哪些是模块设计为公开使用的部分。
- 隐藏内部实现细节(即使某些名称不以
_开头,只要不在__all__中,也不会被import *导入)。
示例解析
在代码:
__all__ = ['StorageConfig']
- 含义:
- 该模块仅公开一个名为
StorageConfig的对象(通常是一个类或配置对象)。 - 当用户使用
from your_module import *时:# 只会导入 StorageConfig,其他名称不会被导入 from your_module import * print(StorageConfig) # 可用 print(SomeInternalClass) # 报错 NameError
- 该模块仅公开一个名为
使用场景
假设模块文件 config.py 内容如下:
class StorageConfig: ... # 公开的配置类
class _InternalHelper: ... # 内部工具(以下划线开头,默认隐藏)
def connect(): ... # 未在 __all__ 中,但以字母开头
__all__ = ['StorageConfig'] # 只公开 StorageConfig
- 用户导入效果:
from config import * # 可用 StorageConfig # 不可用(即使 connect 不以 _ 开头) connect # NameError! _InternalHelper # NameError(本来就是隐藏的)
注意事项
显式导入不受影响:
__all__只影响import *。用户仍可显式导入未在__all__中的名称:from your_module import connect # 允许文档工具依赖
__all__:
许多自动化文档生成工具(如 Sphinx)会参考__all__来确定哪些对象需要被文档化。包中的
__init__.py:
在包的__init__.py文件中,__all__可定义包级别公开的子模块列表:# my_package/__init__.py __all__ = ['submodule1', 'submodule2']
总结
| 代码 | 作用 |
|---|---|
__all__ = ['StorageConfig'] |
声明模块仅公开 StorageConfig 对象,限制 import * 的导入范围。 |
通过定义 __all__,开发者可以更精确地控制模块的公共接口,避免内部实现被意外暴露。