python的源码中,经常会看到的 __all__ 列表变量的概念和作用详解

概念

__all__ 是 Python 模块中的一个特殊变量,用来显式定义当使用 from module import * 时,从模块中导出哪些对象(变量、函数、类等)。

默认情况下,from module import * 会导入所有非以下划线 _ 开头的公开对象。(也就是非私有对象)
但当模块中定义了 __all__ 列表时,它会限制导出的内容,仅包含列表中的名称。

 

通俗解释

  • 想象模块是一个工具箱(module),里面有很多工具(变量、函数、类等)。
  • __all__ 就是一个清单,告诉别人“如果你直接用 from 工具箱 import * 的话,这些工具(清单里的)是你能拿走的,其他工具不提供。”
  • 如果没有 __all__,别人可以拿走几乎所有公开的工具(除非以 _ 开头的工具)。

 

举例说明

模块定义

假设你有一个模块 my_module.py

# my_module.py

# 公共函数
def function1():
    return "This is function1"

def function2():
    return "This is function2"

# 内部使用的私有函数
def _function3():
    return "This is function3"

# 公共类
class Class1:
    pass

# 公共变量
CONSTANT = 42

# 定义 __all__
__all__ = ['function1', 'Class1', 'CONSTANT']

导入的行为

1.使用 from my_module import *

from my_module import *
print(function1())  # 输出: This is function1
print(Class1)       # 输出: <class 'my_module.Class1'>
print(CONSTANT)     # 输出: 42
print(function2())  # 抛出错误: NameError: name 'function2' is not defined
print(_function3()) # 抛出错误: NameError: name '_function3' is not defined

解释只有 __all__ 列表中的 function1Class1CONSTANT 被导入。

 

2.直接导入模块,不受 __all__ 限制.

import my_module
print(my_module.function1())  # 输出: This is function1
print(my_module.function2())  # 输出: This is function2
print(my_module._function3()) # 输出: This is function3

解释:直接导入模块时,__all__ 不生效,模块中的所有内容都可以通过 模块名.名称 访问。

 

使用场景

    1. 明确接口
      __all__ 是模块开发者用来指定模块的公开 API 的好工具,能够帮助用户快速了解模块的核心功能,同时隐藏不必要的内部细节。

    2. 避免命名冲突
      如果模块中有很多内部变量、函数或类,不希望用户通过 from module import * 导入后意外覆盖现有名称,可以用 __all__ 限制导出范围

 

不定义 __all__ 的行为

# 模块没有定义 __all__
def func1(): pass
def func2(): pass
_var = 123  # 私有变量

# 导入行为
from module import *
print(func1)  # 会导入
print(func2)  # 会导入
print(_var)   # 不会导入,私有变量被屏蔽

如果没有定义 __all__

  • from module import * 会导入所有非私有对象(未以下划线 _ 开头的对象)。

注意事项

    1. 明确约定:定义了 __all__ 的模块,外部用户应以 __all__ 的内容为模块的公开 API,其它未列入 __all__ 的内容即使能访问,也应视为内部实现,可能随时改变。

    2. 不建议滥用 from module import *
      导入时推荐显式列出需要的对象,例如:

from my_module import function1, Class1

 

posted @ 2024-12-13 15:22  AlphaGeek  阅读(1434)  评论(0)    收藏  举报