__all__ 是干嘛用的?

时间:2022-07-23
本文章向大家介绍__all__ 是干嘛用的?,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

前言

前两天写代码的时候在一个简单的导入操作上竟然卡了有半小时之多,弄了半天才发现问题所在,分享给大家,希望对大家有所借鉴。

from 模块 import *

我们导入模块通常用 from 模块名 import * , 之前我一直认为,就是导入这个模块内的所有属性和方法,但事实并非如此,python 通过 __all__内置变量来决定 哪些属性和方法可供外部使用,我们具体来看例子:

我们首先创建个 了 text1.py 文件 ,内容如下:

# 测试变量
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()

我们可以看到 ,在test1.py模块文件内部,我们可以顺利的调用所有的测试变量,测试类,测试方法,另外,我们在模块文件内部定义了 __all__ = ['param1', 'test1', 'Test1'],这个有什么用呢,我们暂时看不出.

我们再新建个test2.py文件,内容如下:

from test1 import *
try:
    print(param1)
except NameError as err:
    print(err, ", no variable param1")
try:
    print(param2)
except NameError as err:
    print( "no variable param2")
try:
    test1()
except NameError as err:
    print(err, ", no method test1()")
try:
    test2()
except NameError as err:
    print("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("no class T2()")

执行结果如下:

param1
no variable param2
method test1() has been used
no method test2()
class Test1() has been used!
no class T2()

从执行结果可以看出,虽然我们在test2.py文件开头就用from test1 import * 导入了test1 模块中的所有变量和 函数方法,但从结果似乎不是如此,param2,test2(),和Test2都找不到,也就是没导入进来,而这几个变量或者方法恰恰是 在 test1.py 模块文件中的 __name__ 变量没有定义的, 所以,并不是 from 模块名 import *就导入 该模块的所有内容,而是一次导入模块中通过__all__变量指定的所有对象。所以,我们可以通过__all__变量 来决定哪些内容是否要提供给外部调用。

思考题 ,模块中 定义的私有变量(单下划线或双下划线) 是否也受 all 变量控制?