Python __all__变量用法

在默认情况下,如果使用“from 模块名 import *”这样的语句来导入模块,程序会导入该模块中所有不以下画线开头的成员(包括变量、函数和类)。但在一些场景中,我们并不希望每个成员都被暴露出来供外界使用,此时可借助于模块的 __all__ 变量,将变量的值设置成一个列表,只有该列表中的成员才会被暴露出来。

例如,下面程序定义了一个包含 __all__ 变量的模块:
'''测试__all__变量的模块'''
def hello():
    print("Hello, Python")
def world():
    print("Pyhton World is funny")
def test():
    print('--test--')
# 定义__all__变量,指定默认只导入hello和world两个成员
__all__ = ['hello', 'world']
上面的 __all__ 变量指定该模块默认只被导入 hello 和 world 两个成员。下面程序示范了模块中 __all__ 变量的用处:
# 导入all_module模块内所有成员
from all_module import *
hello()
world()
test() # 会提示找不到test()函数
上面第 2 行代码使用“from all_module import *”导入了 all_module 模块下所有的成员。由于该模块包含了 __all__ 变量,因此该语句只导入 __all__ 变量所列出的成员。

运行上面程序,可以看到如下输出结果:

Hello, Python
Python World is funny
Traceback (most recent call last) :
  File "all_module_test.py", line 20, in <module>
    test() #会提示找不到test()函数
NameError: name 'test' is not defined

从上面的输出结果可以看到,通过“from all_module import *”语句确实只能导入 __all__ 变量所列出的全部成员,没有列出的 test 就没有被导入进来。

事实上,__all__ 变量的意义在于为模块定义了一个开放的公共接口。通常来说,只有 __all__ 变量列出的成员,才是希望该模块被外界使用的成员。因此,为模块设置 __all__ 变量还是比较有用的。比如一个实际的大模块可能包含了大量其他程序不需要使用的变量、函数和类,那么通过 __all__ 变量即可把它们自动过滤掉,这还是非常酷的。

如果确实希望程序使用模块内 __all__ 列表之外的成员,有两种解决方法:
  • 第一种是使用“import 模块名”来导入模块。在通过这种方式导入模块之后,总可以通过模块名前缀(如果为模块指定了别名,则可以使用模快的别名作为前缀)来调用模块内的成员。
  • 第二种是使用“from 模块名 import 成员”来导入指定成员。在这种方式下,即使想导入的成员没有位于 __all__ 列表中,也依然可以导入。