1 为什么会有`__all__`?
Java、C++等面向对象语言,会使用如public、private、protect等之类的关键字限定一个程序文件中类、变量、方法的被外部程序调用的作用域。
Python是一种编写比较简洁的编程语言,Python为实现类似于Java那种使用关键字的方式限定变量等内容的跨程序的作用域限制,便使用了`__all__`这个魔法函数来实现。
在看一些Python源码的时候你会发现这种使用方式很普遍,也是一种很标准的书写方法。如果你想进一步深入了解Python的话了解`__all__`相关内容也是必须的。
2 如何使用
它是一个string元素组成的list变量,定义了当你使用 from import * 导入某个模块的时候能导出的符号(这里代表变量,函数,类等)。
以下为要被其他程序调用的程序,程序文件名称为:aias_test.py:# -*- encoding: utf-8 -*-
# 测试变量
param1 = "param1"
param2 = "param2"
# 测试函数
def test1():
print("method test1() has been used")
def test2():
print("method test2() has been used")
# 测试类, 这里重新了对象的可调用方法__call__
class Test1():
def __call__(self):
print("class Test1() has been used!")
class Test2():
def __call__(self):
print("class Test2() has been used!")
__all__ = ['param1', 'test1', 'Test1']
if __name__ == "__main__":
# 当前程序文件使用相关变量、方法、类
print(param1, param2)
test1()
test2()
T1 = Test1()
T1()
T2 = Test2()
T2()
1. 当前程序测试,也就是当前程序内可以使用所有相关的全局(需要注意变量的作用域)变量,程序运行如下:
2. 其他程序调用当前程序,# -*- encoding: utf-8 -*-
from aias_test import * # 导入aias_test中所有可以导入的变量、方法、类等
# 测试
try:
print(param1)
except NameError as err:
print(err, ", no variable param1")
try:
print(param2)
except NameError as err:
print(err, ", no variable param2")
try:
test1()
except NameError as err:
print(err, ", no method test1()")
try:
test2()
except NameError as err:
print(err, ", no method test2()")
try:
T1 = Test1()
T1()
except NameError as err:
print(err, ", no calss Test1()")
try:
T2 = Test2()
T2()
except NameError as err:
print(err, ", no class T2()")
其运行如下:
3 总结
看到上面的示例,相信你已经会使用`__all__`这个魔法函数了。其实`__all__`在一个函数包中可指定哪些单个的py文件能够被导入,一个复杂的、功能强大的Python工具包会有很多级被调用的内容,上面也只是介绍了一个脚本文件中的变量、方法、类的情况而已,当然在更高一级的包中(一个文件夹中有多个py文件)会有一个`__init__.py`的文件,在这个文件书写`__all__`可以指定那些py文件可以被使用。当然党`__all__`没有指定内容的话,就默认全部可以使用。