第10.4节 Python模块的弱封装机制
一、 引言
Python模块可以为调用者提供模块内成员的访问和调用,但某些情况下, 因为某些成员可能有特殊访问规则等原因,并不适合将模块内所有成员都提供给调用者访问,此时模块可以类似类的封装机制类似的模式提供一定的内部成员保护。
模块内的内部成员封装机制有两种,一种是定义类似类的私有成员,二是类似类的__slots__实例属性白名单机制,下面分别介绍这两种方法。
二、 定义模块的私有成员
在模块内,一个以下划线开头的成员属于模块的私有成员,在使用“from 模块名 import *”不会被导入,这和类的私有成员管理比较像,但还是有如下区别:
1、 下划线开头的成员包括了单下划线开头、双下划线开头、双下划线开头双下划线结尾的成员,它们的处理是一样的,而类中它们是不一样的,具体大家可参考《第7.8节 Python中隐秘的类封装方法》;
2、 模块的私有成员使用“from 模块名 import *”这样的语句来导入模块时,程序会跳过下划线开头的模块成员,即下划线开头的所有成员都不能“from 模块名 import *”导入,但可以通过“import 模块名”或“from 模块名 import 成员”方式导入。
Python通过这种简单的名字规则来隐藏成员的方法就是模块的封装机制,可以看到其实这种封装机制很脆弱。
3、 案例:
我们定义一个imptest.py,文件内容如下:
#imptest.py
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....")
print("Now in imptest module!")
1)使用“from 模块名 import *”导入并调用成员执行验证是否导入成功:
>>> from imptest import *
Now in imptest module!
>>> f()
execute ftest function in imptest....
>>> _f1()
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
_f1()
NameError: name '_f1' is not defined
>>> __f2()
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
__f2()
NameError: name '__f2' is not defined
>>> __f3__()
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
__f3__()
NameError: name '__f3__' is not defined
>>>
可以看到凡是带下划线的都没有导入。
2) 使用“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....
>>>

可以看到都能正常导入使用。
本节介绍了模块中使用下划线开头定义成员能防止“from 模块名 import *”导入这些成员,这是一种Python提供的弱封装机制,但建议大家在使用时还是遵循这种机制。
老猿Python,跟老猿学Python!
博客地址:https://blog.csdn.net/LaoYuanPython
请大家多多支持,点赞、评论和加关注!谢谢!
第10.4节 Python模块的弱封装机制的更多相关文章
- 第10.11节 Python模块和包小结
Python的模块就是一个独立的Python文件,Python的包是一些功能相关的Python文件放到一个目录下进行统一管理的文件管理结构,包本质上是模块,加载包就是加载包下特定的模块文件__init ...
- 第10.8节 Python包的导入方式详解
一. 包导入与模块导入的关系 由于包本质上是模块,其实对模块的许多导入方法都适用于包,但由于包的结构与模块有差异,所以二者还是有些区别的: 对包的导入,实际上就是包目录下的__init__.py文件的 ...
- 第10.9节 Python子包的导入方式介绍
在<第10.8节 Python包的导入方式详解>详细介绍了包的导入方式,子包也是包,子包的导入与包的导入方法上没有本质区别,但二者还是有所不同.本节对照二者的方式介绍子包与包导入的关系: ...
- 第10.7节 Python包和子包的定义步骤
一. 包的定义步骤 按照包名创建或使用一个已有目录,目录名就是包名,必须注意包的目录必须位于Python加载模块的搜索路径中(具体请参考<第10.1节 Python的模块及模块导入>关于模 ...
- 第10.6节 Python包的概念
一. 引言 在<第10.2节 Python的模块及模块导入>介绍了模块的概念及导入的几个关键点,Python中的模块是一个单个的py文件,当我们开发的项目或功能集由多个文件构成时,我们需要 ...
- 第10.3节 Python导入模块能否取消导入?
模块导入后,是否可以取消导入?实际上当模块导入后,是无法逆向还原到导入前的状态的,但是可以利用"del 模块名"进行导入模块的删除,此时的删除只是删除了导入模块对应的模块变量名,删 ...
- 第10.1节 Python的模块及模块导入
一. 什么是模块 Python中的模块即单个的Python代码文件,为什么称为模块呢?这是因为在Python中,每个独立的Python文件都可以作为被其他代码导入的模块使用,导入的模块有自己的名字空间 ...
- 第10.5节 使用__all__定义Python模块导入白名单
一. 引言 <第10.4节 Python模块的弱封装机制>介绍了Python模块的的弱封装机制,除了使用弱封装机制来从一定程度上防止导入特定成员外,Python模块中还提供可另外一种类似白 ...
- 第10.10节 Python使用__init__.py自动加载包下内容
在前面章节老猿介绍了包下模块及子包的加载的各种方式,并说明包的加载首先是自动加载包下的__init__.py文件.在<第10.6节 Python包的概念>中介绍了__init__.py文件 ...
随机推荐
- 【SpringCloud】01.常见软件架构的区别
MVC.RPC.SOA.微服务架构的区别: 一.MVC架构 MVC架构就是一种单体架构. 代表技术:Struts2.SpringMVC.Spring.Mybatis等等. 二.RPC架构 RPC(Re ...
- ci之 core下CodeIgniter源码分析(1)
ci 执行流程 index.php 文件 加载codeigniter文件 codeigniter部分里面加载的: 加载配置文件constants 加载全局公共函数core/Common.php 文件 ...
- Servlet基础使用总结
Servlet通俗理解:主要功能在于交互式地浏览和生成数据,生成动态Web内容.Servlet运行于支持Java的应用服务器中.从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Ser ...
- 使用Graph API 操作OneDrive 文件 权限 共享
(Get)列出默认驱动器下(获取items id) /me/drive/root/children 如果想找其他驱动器使用/Drives 列出后可以查看到驱动器下的文件,其中items id就是文件的 ...
- HTML 5 <input> multiple 属性
<form action="demo_form.asp" method="get"> Select images: <input type=& ...
- [MIT6.006] 22. Daynamic Programming IV: Guitar Fingering, Tetris, Super Mario Bro. 动态规划IV:吉他指弹,俄罗斯方块,超级玛丽奥
之前我们讲到动态规划五步中有个Guessing猜,一般情况下猜有两种情况: 在猜和递归上:猜的是用于解决更大问题的子问题: 在子问题定义上:如果要猜更多,就要增加更多子问题. 下面我们来看如果像背包问 ...
- linux文件增删拷(touch/mkdir/cp/mv/rm)
touch或>命令创建普通文件: [root@localhost test]# touch a ---创建单个文件 [root@localhost test]# ls a [root@loca ...
- windows下命令行设置静态IP
windows 10 预览版出现无法设置静态IP的bug,只能通过命令行进行设置,开启powershell,然后执行下列的命令即可 下面的"以太网 3" 为你设置的网卡的网卡名称, ...
- Avoided redundant navigation to current location: "/users"
问题产生的原因:在Vue导航菜单中,重复点击一个菜单,即重复触发一个相同的路由,会报错,但不影响功能 解决:在router的配置文件中加入如下代码: const originalPush = Rout ...
- BurpSuite多重代理的情形
有时候为了隐藏自己的真实IP,访问目标网站需要走代理.比如说,通过代理IP访问目标网站并且代理IP可以随时切换,这样可以避免IP被封堵后无法访问目标网站的尴尬. 一. 首先把代理切换为全局模式 操作步 ...