在 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__
,开发者可以更精确地控制模块的公共接口,避免内部实现被意外暴露。