概述
熟悉C++、JAVA的小伙伴,都知道在C++、JAVA中有访问控制权限,比如public、private等,可以控制类、变量、方法是否可以在外部访问。
在python中,没有访问控制权限,需要大家自觉遵守的“约定”下工作
用 __all__变量 暴露接口,这也是一种约定。相当于C++、JAVA的public关键字
作用:
控制 from xxx import * 的行为
无效
对于import xxx或者from xxx import xxx,均无效
写在普通.py文件中
util.py文件内容如下:
# coding=utf-8
__all__=['add']
_content='python'
def add(a,b):
return a+b
def fun():
print('_content=',_content)
上面的__all__中暴露了add()函数
main.py文件内容如下,(使用from util import *):
# coding=utf-8
from util import *
sum=add(1,2)
print(sum)
fun() # 报错
print(_content) # 报错
执行main.py文件,观察报错
修改 main.py文件,内容如下:
(使用from util import add,fun,_content):
# coding=utf-8
from util import add,fun,_content
sum=add(1,2)
print(sum)
fun()
print(_content)
执行main.py文件,能够正常执行
总结:
变量__all__只对from util import *有访问控制作用
写在__init__.py文件中
这种方式应用于包中,写在包中的__init__.py文件里,如下:
__all__=["module_a","module_b"]
在使用 from package_name import * 时 , 表示 导入 该 包 中的 两个 module_a模块 和 module_b模块
定义__all__注意的地方
__all__应该是 list 类型的
不应该 动态生成 ,比如使用列表解析式。__all__的作用就是定义公开接口,如果不以字面量的形式显式写出来,就失去意义了。即使有了
__all__, 也不应该在非临时代码中使用 from xxx import * 语法按照 PEP8 建议的风格,
__all__应该写在所有 import 语句下面,在函数、常量等定义的上面。
如果一个模块需要暴露的接口改动频繁,__all__ 可以这样定义:
__all__ = [
"foo",
"bar",
"egg",
]
最后多出来的逗号在 Python 中是允许的,也是符合 PEP8 风格的。这样修改一个接口的暴露就只修改一行,方便版本控制的时候看 diff。
感谢:
https://www.cnblogs.com/shengulong/p/7425088.html
https://www.cnblogs.com/yanxiatingyu/p/9362525.html