在认识这个魔法方法之前,一直认为from module import *
会将模块内的变量和方法都导入,但是事实并不是这样的,Python是通过__all__
这个内置的变量来决定哪些内容会被外部导入。让我们用代码来发现其中的奥秘:
用来测试的模块命名为demo1.py
我们可以看到 ,在demo1.py
模块内部,对变量进行打印,对函数进行调用,都是正常进行的,接下来我们在模块demo2.py
中导入试试看
from demo1 import *
print(var1)
print(var2)
func1()
func2()
# 输出
nancy
peter
i am func1
i am func2
这是正常操作,下面在demo1.py
中加入魔法方法__all__
,在本模块的输出并没有什么变化
var1 = 'nancy'
var2 = 'peter'
def func1():
print('i am func1')
def func2():
print('i am func2')
__all__ = ['var1', 'func1']
if __name__ == '__main__':
print(var1)
print(var2)
func1()
func2()
# 输出
nancy
peter
i am func1
i am func2
看下在demo2.py
中的变化,首先在IDE中已经提示报错,执行看下结果
为了使结果更加清晰,加入捕捉异常代码
from demo1 import *
try:
print(var1)
except NameError as e:
print('var1 not found')
try:
print(var2)
except NameError as e:
print('var2 not found')
try:
func1()
except NameError as e:
print('func1 not found')
try:
func2()
except NameError as e:
print('func2 not found')
# 输出
nancy
var2 not found
i am func1
func2 not found
这下一目了然的看出__all__
的作用,虽然我们在demo2.py
文件开头就用from demo1 import *
导入了demo1
模块中的所有变量和函数,但是却不能访问到所有的变量和函数,而是只能访问到定义到__all__
变量中的对象。所以,我们可以通过__all__
变量来决定哪些内容是否要提供给外部调用。
但是还有一个问题值得思考,模块中的私有变量或私有方法是否可以加在__all__
变量中呢,下面来做测试
demo1.py
var1 = 'nancy'
__var2 = 'peter'
# __all__ = ['var1', '__var2']
在demo2.py
中的表现,正常导入后,访问不到私有变量
from demo1 import *
try:
print(var1)
except NameError as e:
print('var1 not found')
try:
print(__var2)
except NameError as e:
print('var2 not found')
# 输出
nancy
var2 not found
打开__all__
变量后的输出
# 输出
nancy
peter
所以结果是:将私有变量添加到__all__
变量中后,在其他模块导入后可以访问到私有变量