第7.8节 Python中隐秘的类封装方法
前面章节已经介绍了Python中的多态和继承,本节将介绍面向对象程序设计OOP三大特征的另一个特征--封装。
一、 概念
封装是将对象的状态信息(也就是数据、属性)隐藏在对象内部,将对象的属性和实现细节隐藏起来,不允许外部程序直接访问对象内部信息,而是通过类所提供的方法来实现对内部信息的操作和访问,让方法来控制对这些属性进行安全的访问和操作。实际上封装有两个方面的含义:把该隐藏的隐藏起来,把该暴露的暴露出来。
封装除了隐藏类的数据和实现细节外,可以达到如下目的:
1. 让调用方只能通过类定义的方法来访问类和对象内部的属性和数据,从而可以在相关方法里加入控制逻辑,对数据进行检查和处理,确保属性的访问符合设计者的预期;
2. 便于修改,所有对该数据的访问都通过方法进行,开发人员只需要保证调用格式和返回数据格式保持不变就可以兼容原有的调用代码,无需修改调用方代码,提高代码的可维护性。
二、 Python封装机制
在大部分面向对象开发的语言如c++和Java语言中,封装是通过私有成员和方法实现的,而Python没有显示定义私有成员的方法,其封装是利用了变量和方法命名的特殊处理来实现的。具体来说:
1. 如果要让内部属性不被外部访问,可以把属性(含方法)的名称前加上两个下划线,在Python中,实例的变量名和方法名如果以两个下划线开头(但不能是两个下划线结尾),就变成了一个私有变量(private),只有内部可以访问,外部不能访问:
1) Python的私有变量,直接在外部通过实例是无法访问的;
2) Python私有变量的实现方式是,在Python编译时,对于类定义中所有以两个下划线打头(但不能是两个下划线结尾)的名称都进行转换,在开头加上一个下划线和类名;
3) Python这种幕后处理手法,使得开发人员能通过名字变换从类和对象外访问私有属性和方法,但这种方式应该禁止,因为直接访问可能导致程序不能遵循设计和开发人员对数据的控制,导致意外的错误。
2. 在Python中,变量名类似__xxx__的,也就是以双下划线开头并且以双下划线结尾的变量和方法,是特殊变量,特殊变量是可以直接访问的,不是私有变量,所以,一般实例变量和类变量以及方法不能用__xxx__这样的方式命名;
3. 在Python中,除了双下划线开头变量是私有变量外,还有一种变量名或方法名以一个下划线开头,这样的实例变量和方法外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,请视为私有变量不要随意访问。Python对这种变量,执行from module import * 不会导入,也就是说import如果不指定导入的方法名,导入时对模块中以一个下划线打头的名称的方法不会导入。
从上所述,Python的封装与常规的OOP语言差异比较大,它没有为私有属性提供直接的支持,要让方法或属性成为私有的,只需让其名称以两个下划线打头即可。这种处理要求程序员知道在什么情况下从外部修改属性是安全的。因此Python无法禁止别人访问对象的私有方法和属性,但这种名称修改方式发出了强烈的信号,让他们不要这样做。
本节介绍了Python中类的封装机制,下节将结合一个案例详细说明。
老猿Python(https://blog.csdn.net/LaoYuanPython)系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。
欢迎大家批评指正,谢谢大家关注!
第7.8节 Python中隐秘的类封装方法的更多相关文章
- 第7.4节 Python中与众不同的类
一. 引言 在较旧的Python版本中,类型和类之间泾渭分明:内置对象是基于类型的,而自定义对象是基于类的.因此,你可以创建类,但不能创建类型.在较新的Python 2版本中,这种差别不那么明显 ...
- 第7.19节 Python中的抽象类详解:abstractmethod、abc与真实子类
第7.19节 Python中的抽象类详解:abstractmethod.abc与真实子类 一. 引言 前面相关的章节已经介绍过,Python中定义某种类型是以实现了该类型对应的协议为标准的,而不 ...
- 第7.15节 Python中classmethod定义的类方法详解
第7.15节 Python中classmethod定义的类方法详解 类中的方法,除了实例方法外,还有两种方法,分别是类方法和静态方法.本节介绍类方法的定义和使用. 一. 类方法的定义 在类中定 ...
- 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解
第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一. 引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...
- 第7.22节 Python中使用super调用父类的方法
第7.22节 Python中使用super调用父类的方法 前面章节很多地方都引入了super方法,这个方法就是访问超类这个类对象的.由于super方法的特殊性,本节单独谈一谈super方法. 一.su ...
- 第8.23节 Python中使用sort/sorted排序与“富比较”方法的关系分析
一. 引言 <第8.21节 Python中__lt__.gt__等 "富比较"("rich comparison")方法用途探究>和<第8.2 ...
- 第8.27节 Python中__getattribute__与property的fget、@property装饰器getter关系深入解析
一. 引言 在<第7.23节 Python使用property函数定义属性简化属性访问的代码实现>和<第7.26节 Python中的@property装饰器定义属性访问方法gette ...
- 第11.20节 Python 中正则表达式的扩展功能:后视断言、后视取反
一. 引言 在<第11.19节 Python 中正则表达式的扩展功能:前视断言和前视取反>中老猿介绍了前视断言和前视取反,与二者对应的还有后视断言和后视取反. 二. (?<=-)后视 ...
- 第14.12节 Python中使用BeautifulSoup解析http报文:使用select方法快速定位内容
一. 引言 在<第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问>和<第14.11节 Python中使用BeautifulSo ...
随机推荐
- js 图片放大镜功能
原理:放置两张相同的图片,一张作为主图片(图片1),另一张作为用来裁剪并放大的图片(图片2) 鼠标移动时,计算鼠标在图片1的位置(距离图片1左上角的x,y距离),以此决定在图片2开始 ...
- C# 集合类(三)
C# 集合类自己经常用到: 数组(Array).动态数组(ArrayList).列表(List).哈希表(Hashtable).字典(Dictionary),对于经常使用的这些数据结构,做一个总结,便 ...
- 9个JavaScript日常开发小技巧
1.生成指定范围的数字 在某些情况下,我们会创建一个处在两个数之间的数组.假设我们要判断某人的生日是否在某个范围的年份内,那么下面是实现它的一个很简单的方法 1 2 3 4 5 6 let start ...
- layui表单提交与ajax访问webapi
啊啊啊啊 这个东西实在很蛋疼啊 每次访问webapi就很老火 这里就一下 以后忘记的话就来查阅 不多说 直接开始 首先html页面 新建一个基于layui的form表单页面LayuiForm.csh ...
- VirtualBox 6 安装 CentOS 7
1 安装环境 windows7 Oracle VM VirtualBox 6.0.24 CentOS 7 2 VirtualBox 6 - 虚拟机软件 2.1 下载 Oracle VM Virtual ...
- 打包项目成war包并部署到服务器上,项目运行一直显示加载中
查看服务器上的Tomcat路径下的log 显示 org.apache.catalina.LifecycleException: Failed to initialize component [Conn ...
- linux kernel RCU 以及读写锁
信号量有一个很明显的缺点,没有区分临界区的读写属性,读写锁允许多个线程进程并发的访问临界区,但是写访问只限于一个线程,在多处理器系统中允许多个读者访问共享资源,但是写者有排他性,读写锁的特性如下:允许 ...
- redis-server文件启动cmd一闪而过
工作上需要在本地装redis,所以就帮别人排查了一个问题,就是redis服务双击了之后不能起来,就是一个黑色的cmd框一闪而过,正常的是这样的: 然而,我当时第一次接触windows上的redis服务 ...
- MySQL全面瓦解12:连接查询的原理和应用
概述 MySQL最强大的功能之一就是能在数据检索的执行中连接(join)表.大部分的单表数据查询并不能满足我们的需求,这时候我们就需要连接一个或者多个表,并通过一些条件过滤筛选出我们需要的数据. 了解 ...
- python菜鸟教程学习4:基本数据类型
变量:python中的变量不需要声明,但在使用前都必须要赋值,变量赋值之后才会被创建 在python中变量是没有类型的,所有的数据类型是对内存中对象的类型. 赋值:使用等号=来给变量赋值 python ...