第10.5节 使用__all__定义Python模块导入白名单
一、 引言
《第10.4节 Python模块的弱封装机制》介绍了Python模块的的弱封装机制,除了使用弱封装机制来从一定程度上防止导入特定成员外,Python模块中还提供可另外一种类似白名单的机制来控制导入的成员,这个机制就是在模块中定义__all__变量,将__all__的值设置成一个列表,只有列表中的模块成员才能被导入。
二、 方法介绍
在模块内部定义一个模块内的全局变量__all__,其元素是每个需要允许导出的成员名字符串。
all = [‘成员名1’,…,‘成员名n’]
三、 案例
1、 我们定义一个imptest模块,包括三个成员变量和5个成员函数,内容如下:
#imptest.py
__all__=['f','_f1','var2','_var3']
var1,var2,_var3='imptest var1','imptest var2','imptest _var3'
_var2
def f():
print("execute ftest function in imptest....")
def _f1():
print("execute _f1(单下划线开头) function in imptest....")
def __f2():
print("execute __f2(双下划线开头) function in imptest....")
def __f3__():
print("execute __f3__(双下划线开头结尾) function in imptest....")
def f4():
print("execute f4 function in imptest....")
print("Now in imptest module!")
2、 使用“from 模块名 import *”导入imptest模块的成员并执行验证是否导入成功
>>> from imptest import *
Now in imptest module!
>>> var1
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
var1
NameError: name 'var1' is not defined
>>> var2
'imptest var2'
>>> _var3
'imptest _var3'
>>> f()
execute ftest function in imptest....
>>> _f1()
execute _f1(单下划线开头) function in imptest....
>>> __f2()
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
__f2()
NameError: name '__f2' is not defined
>>>
执行截图:
从上述执行情况来看,只有在__all__列表中的成员才能通过“from imptest import *”导入,带下划线的也会正常导入,没有在__all__列表中的成员计算无下划线开头也不能导入。
3、 直接使用“import 模块名”导入
源代码:
>>> import imptest
Now in imptest module!
>>> imptest.f()
execute ftest function in imptest....
>>> imptest._f1()
execute _f1(单下划线开头) function in imptest....
>>> imptest.__f2()
execute __f2(双下划线开头) function in imptest....
>>> imptest.__f3__()
execute __f3__(双下划线开头结尾) function in imptest....
>>> imptest.var1,imptest.var2,imptest._var3
('imptest var1', 'imptest var2', 'imptest _var3')
>>>
执行截屏:
从上述执行情况来看,使用“import 模块名”导入后,所有成员都可以正常访问,不受__all__列表的影响。
四、 总结
使用__all__定义模块访问白名单:
- 只对“from 模块名 import *”导入产生影响,对“import 模块名”或“from 模块名 import 成员名”不产生影响;
- 在__all__列表中的元素不论是否带下划线开头,“from 模块名 import *”都会导入,不受模块的缺省封装机制影响,可以说这是另一种方式的封装;
- 在模块定义__all__变量后,可以使用“
模块.__all__
”查看模块建议使用的模块成员。
__all__
变量可以认为给模块定义了一个开放的公共接口。通常来说,只有__all__
变量列出的模块属性,才是该模块建议外界使用的。因此,为一个大模块定义__all__ 变量,就可以给调用程序建议过滤不需要使用的变量、函数和类,只使用__all__定义的白名单属性。
前面章节介绍过 dir(模块名)可返回模块或类所包含的全部程序单元(包括变量、函数、类和方法等),但直接使用 dir() 函数默认会列出模块内所有的属性,包括以下划线开头的属性,如果模块定义了__all__ 变量,则建议调用者只关注__all__ 变量限定的属性。
第10.5节 使用__all__定义Python模块导入白名单的更多相关文章
- python模块导入细节
python模块导入细节 官方手册:https://docs.python.org/3/tutorial/modules.html 可执行文件和模块 python源代码文件按照功能可以分为两种类型: ...
- 【转】python模块导入细节
[转]python模块导入细节 python模块导入细节 官方手册:https://docs.python.org/3/tutorial/modules.html 可执行文件和模块 python源代码 ...
- python模块导入总结
python模块导入总结 模块导入方式 定义test.py模块 def print_func(): print("hello") import 语句 导入模块语法 import m ...
- 一文解决python模块导入
python 模块导入 原理 查找是按照 sys.path 中的路径挨个扫描.若都不存在则提示error. sys.path路径第一个是当前运行脚本所在的目录,其后是PYTHONPATH(一般若步专门 ...
- 详解Python模块导入方法
python常被昵称为胶水语言,它能很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松联结在一起.python包含子目录中的模块方法比较简单,关键是能够在sys.path里面找到通向模块文件的 ...
- python 模块导入import和import from区别
模块就是一个.py文件,在名字空间下导入模块导入import和import from,那么python 模块导入import和import from区别是什么呢 1,import 导入模块 impor ...
- 第8.20节 Python中限制动态定义实例属性的白名单:__slots__
一. 引言 按照<第7.10节 Python类中的实例变量定义与使用>.<第7.14节Python类中的实例方法解析>中的介绍,当定义了一个类,并且创建了该类的实例后,可以给该 ...
- python 模块导入
1. 模块导入: 要使用一个模块,我们必须首先导入该模块.Python使用import语句导入一个模块.例如,导入系统自带的模块 math: import math 你可以认为math就是一个指向已导 ...
- python模块导入-软件开发目录规范-01
模块 模块的基本概念 模块: # 一系列功能的结合体 模块的三种来源 """ 模块的三种来源 1.python解释器内置的模块(os.sys....) 2.第三方的别人写 ...
随机推荐
- 学习笔记——ESP8266项目的例子编译时发生cannot find -lstdc++问题的解决
在尝试对进行ESP8266项目的例子进行编译时发生cannot find -lstdc++问题 第一想法是安装libstdc++,结果安装时又发生了下面的情况: 再次查找原因,最后发现当前安装的交叉编 ...
- Flink SQL Client综合实战
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- nginx&http 第三章 ngx 请求处理的 11 个阶段 --ngx_http_process_request& ngx_http_handler
ngx_http_process_request如果设置了定时器则删除,既然所有的请求已经接收完毕,就不会再发生超时了 重设连接的读写回调函数 重设请求读事件回调函数 调用 ngx_http_hand ...
- SpringBoot微服务框架
springboot 是什么? 配置如何编写 yaml 自动装配原理 集成Web开发 集成数据库Druid 分布式开发:Dubbo(RPC)+zookeeper swagger:接口文档 任务调度 S ...
- 用seaborn绘制散点图
散点图可以显示观察数据的分布,描述数据的相关性,matlibplot也可以绘制散点图,不过我一般优先使用seaborn库的sctterplot()绘制,下面就介绍一下如何用seaborn.scatte ...
- python 与 百度人脸识别api
用python来做人脸识别代码量少 思路清晰, 在使用之前我们需要在我们的配置的编译器中通过pip install baidu-aip 即可 from aip import AipFac ...
- android开发导包升级到androidx踩坑记录【转载】
最近一直在做安卓开发,奈何手中的资料比较老,资料上的一些Import经常没有,十分让人头疼. 感谢简书上的[张晴天天天天天]做的整理. 在这里也记录一下备用. 升级Android Studio后,在 ...
- Spring之事务源码
对@Transactional注解的类进行动态代理 同前文<Spring AOP源码分析>中分析动态代理入口一样,都是在initializeBean时执行. Object exposedO ...
- Vue 计算属性与方法
computed 基本使用 如果数据需要有复杂的计算,则可以在Vue实例中定义计算属性,再交由mustache进行渲染. computed内部其实是通过getttr实现的,所以不用加括号即可完成其下方 ...
- 为什么说线程太多,cpu切换线程会浪费很多时间?
问题1: 假如有一个计算任务,计算1-100的和,每10个数相加,需要占用一个cpu时间片(1s).如果起一个线程(模拟没有线程切换),完成任务需要多长时间?如果起5个线程,完成任务需要消耗多久时间? ...