一、 引言

《第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__定义模块访问白名单:

  1. 只对“from 模块名 import *”导入产生影响,对“import 模块名”或“from 模块名 import 成员名”不产生影响;
  2. 在__all__列表中的元素不论是否带下划线开头,“from 模块名 import *”都会导入,不受模块的缺省封装机制影响,可以说这是另一种方式的封装;
  3. 在模块定义__all__变量后,可以使用“模块.__all__”查看模块建议使用的模块成员。

__all__变量可以认为给模块定义了一个开放的公共接口。通常来说,只有__all__变量列出的模块属性,才是该模块建议外界使用的。因此,为一个大模块定义__all__ 变量,就可以给调用程序建议过滤不需要使用的变量、函数和类,只使用__all__定义的白名单属性。

前面章节介绍过 dir(模块名)可返回模块或类所包含的全部程序单元(包括变量、函数、类和方法等),但直接使用 dir() 函数默认会列出模块内所有的属性,包括以下划线开头的属性,如果模块定义了__all__ 变量,则建议调用者只关注__all__ 变量限定的属性。

第10.5节 使用__all__定义Python模块导入白名单的更多相关文章

  1. python模块导入细节

    python模块导入细节 官方手册:https://docs.python.org/3/tutorial/modules.html 可执行文件和模块 python源代码文件按照功能可以分为两种类型: ...

  2. 【转】python模块导入细节

    [转]python模块导入细节 python模块导入细节 官方手册:https://docs.python.org/3/tutorial/modules.html 可执行文件和模块 python源代码 ...

  3. python模块导入总结

    python模块导入总结 模块导入方式 定义test.py模块 def print_func(): print("hello") import 语句 导入模块语法 import m ...

  4. 一文解决python模块导入

    python 模块导入 原理 查找是按照 sys.path 中的路径挨个扫描.若都不存在则提示error. sys.path路径第一个是当前运行脚本所在的目录,其后是PYTHONPATH(一般若步专门 ...

  5. 详解Python模块导入方法

    python常被昵称为胶水语言,它能很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松联结在一起.python包含子目录中的模块方法比较简单,关键是能够在sys.path里面找到通向模块文件的 ...

  6. python 模块导入import和import from区别

    模块就是一个.py文件,在名字空间下导入模块导入import和import from,那么python 模块导入import和import from区别是什么呢 1,import 导入模块 impor ...

  7. 第8.20节 Python中限制动态定义实例属性的白名单:__slots__

    一. 引言 按照<第7.10节 Python类中的实例变量定义与使用>.<第7.14节Python类中的实例方法解析>中的介绍,当定义了一个类,并且创建了该类的实例后,可以给该 ...

  8. python 模块导入

    1. 模块导入: 要使用一个模块,我们必须首先导入该模块.Python使用import语句导入一个模块.例如,导入系统自带的模块 math: import math 你可以认为math就是一个指向已导 ...

  9. python模块导入-软件开发目录规范-01

    模块 模块的基本概念 模块: # 一系列功能的结合体 模块的三种来源 """ 模块的三种来源 1.python解释器内置的模块(os.sys....) 2.第三方的别人写 ...

随机推荐

  1. go beego框架 入门使用 (一)

    ---恢复内容开始--- 谢谢您花时间读我写的随笔,有问题的话欢迎留言,看到的话都会回复的! beego框架 分为Web版,Api版     api版目录      web版目录      (区别 : ...

  2. 8、Python语法之流程控制

    一 引子 流程控制即控制流程,具体指控制程序的执行流程,而程序的执行流程分为三种结构:顺序结构(之前我们写的代码都是顺序结构).分支结构(用到if判断).循环结构(用到while与for) 二 分支结 ...

  3. 剑指41和为s的连续整数序列

    题目描述 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多久,他 ...

  4. 5.1 ICommand

    1. CanExecute实现 只是将命令绑定到特定控件是不会触发CanExecute方法执行,该方法只是在实例化命令的时候才使用,其余如果需要触发该事件,只能通过后台代码组合触发,如更新一个后台类字 ...

  5. 嗖嗖移动大厅 源代码 Java初级小项目

    今天给大家一个比较综合的项目:嗖嗖移动业务大厅.项目功能很多,概括的功能也很全面.吃透了这个项目,你的java基础部分已经非常棒了!!! 一 . 项目概述 技能要求  使用面向对象设计的思想  合 ...

  6. 依赖注入DI(IOC)容器快速入门

    1.什么是IOC IOC是一种设计模式,全程控制翻转或叫依赖注入.更详细介绍见http://martinfowler.com/articles/injection.html 2.为什么用IOC 我们通 ...

  7. Mac环境MySql初始密码设置

    1. 首先 点击系统偏好设置 -> 点击MySQL, 在弹出的页面中,关闭服务.2. 进入终端命令输出: cd /usr/local/mysql/bin/ 命令,回车.3. 回车后,输入命令:s ...

  8. Docker - 解决容器内获取的时间和主机的时间不一样的问题

    问题背景 分别在容器和主机下执行 date 命令 可以看到,时间是完全不一样的 解决方案 在运行容器时,挂载 /etc/localtime  目录 docker run -d -v /etc/loca ...

  9. [原题复现][极客大挑战 2019]HardSQL(updatexml报错注入)

    简介  原题复现:  考察知识点:SQL注入(报错注入,绕过过滤)  线上平台:https://buuoj.cn(北京联合大学公开的CTF平台 特别感谢!) 榆林学院内可使用信安协会内部的CTF训练平 ...

  10. ATM管理系统(三)

    一.作业信息 博客班级 软件工程 作业要求 作业要求 作业目标 你理解的作业目标具体内容 学号 3180701218 二.题目要求 编写一个ATM管理系统,语言不限,要求应包括以下主要功能:(1)开户 ...