封装
封装(encapsulation)指的是向外部隐藏不必要的细节。这听起来有点像多态(无需知道对象的内部细节就可使用它)。这两个概念很像,因为它们都是抽象的原则。它们都像函数一样,可帮助你处理程序的组成部分,让你无需关心不必要的细节。
但封装不同于多态。多态让你无需知道对象所属的类(对象的类型)就能调用其方法,而封装让你无需知道对象的构造就能使用它。听起来还是有点像?下面来看一个使用了多态但没有使用封装的示例。假设你有一个名为OpenObject的类
>>> o = OpenObject() # 对象就是这样创建的
>>> o.set_name('Sir Lancelot') 
>>> o.get_name() 
'Sir Lancelot'
你(通过像调用函数一样调用类)创建一个对象,并将其关联到变量o,然后就可以使用方法set_name和get_name了(假设OpenObject支持这些方法)。一切都看起来完美无缺。然而,如果o将其名称存储在全局变量global_name中呢?
>>> global_name 
'Sir Lancelot' 
这意味着使用OpenObject类的实例(对象)时,你需要考虑global_name的内容。事实上,必须确保无人能修改它。
>>> global_name = 'Sir Gumby' 
>>> o.get_name() 
'Sir Gumby' 
如果尝试创建多个OpenObject对象,将出现问题,因为它们共用同一个变量。
>>> o1 = OpenObject() 
>>> o2 = OpenObject() 
>>> o1.set_name('Robin Hood') 
>>> o2.get_name() 
'Robin Hood' 
如你所见,设置一个对象的名称时,将自动设置另一个对象的名称。这可不是你想要的结果。
基本上,你希望对象是抽象的:当调用方法时,无需操心其他的事情,如避免干扰全局变量。如何将名称“封装”在对象中呢?没问题,将其作为一个属性即可。
属性是归属于对象的变量,就像方法一样。实际上,方法差不多就是与函数相关联的属性。如果你使用属性而非全局变量重新编写前面的类,并将其重命名为ClosedObject,就可像下面这样使用它:
>>> c = ClosedObject() 
>>> c.set_name('Sir Lancelot') 
>>> c.get_name() 
'Sir Lancelot' 
到目前为止一切顺利,但这并不能证明名称不是存储在全局变量中的。下面再来创建一个对象。
>>> r = ClosedObject() 
>>> r.set_name('Sir Robin') 
r.get_name()
'Sir Robin' 
从中可知正确地设置了新对象的名称(这可能在你的意料之中),但第一个对象现在怎么样了呢?
>>> c.get_name() 
'Sir Lancelot' 
其名称还在!因为这个对象有自己的状态。对象的状态由其属性(如名称)描述。对象的方法可能修改这些属性,因此对象将一系列函数(方法)组合起来,并赋予它们访问一些变量(属性)的权限,而属性可用于在两次函数调用之间存储值。

私有化封装

默认情况下,可从外部访问对象的属性。再来看一下前面讨论封装时使用的示例。
>>> c.name 
'Sir Lancelot' 
>>> c.name = 'Sir Gumby' 
>>> c.get_name() 
'Sir Gumby' 
有些程序员认为这没问题,但有些程序员(如Smalltalk之父)认为这违反了封装原则。他们认为应该对外部完全隐藏对象的状态(即不能从外部访问它们)。你可能会问,为何他们的立场如此极端?由每个对象管理自己的属性还不够吗?为何要向外部隐藏属性?毕竟,如果能直接访问ClosedObject(对象c所属的类)的属性name,就不需要创建方法setName和getName了。
关键是其他程序员可能不知道(也不应知道)对象内部发生的情况。例如,ClosedObject可能在对象修改其名称时向管理员发送电子邮件。这种功能可能包含在方法set_name中。但如果直接设置c.name,结果将如何呢?什么都不会发生——根本不会发送电子邮件。为避免这类问题,可将属性定义为私有。私有属性不能从对象外部访问,而只能通过存取器方法(如get_name和
set_name)来访问。

Python没有为私有属性提供直接的支持,而是要求程序员知道在什么情况下从外部修改属性是安全的。毕竟,你必须在知道如何使用对象之后才能使用它。然而,通过玩点小花招,可获得类似于私有属性的效果。
要让方法或属性成为私有的(不能从外部访问),只需让其名称以两个下划线打头即可。

class Secretive: 
    def __inaccessible(self): 
         print("Bet you can't see me ...") 
    def accessible(self): 
         print("The secret message is:") 
         self.__inaccessible() 
现在从外部不能访问__inaccessible,但在类中(如accessible中)依然可以使用它。
>>> s = Secretive() 
>>> s.__inaccessible() 
Traceback (most recent call last): 
 File "<stdin>", line 1, in <module> 
AttributeError: Secretive instance has no attribute '__inaccessible' 
>>> s.accessible() 
The secret message is: 
Bet you can't see me ... 
虽然以两个下划线打头有点怪异,但这样的方法类似于其他语言中的标准私有方法。然而,幕后的处理手法并不标准:在类定义中,对所有以两个下划线打头的名称都进行转换,即在开头加上一个下划线和类名。
>>> Secretive._Secretive__inaccessible 
<unbound method Secretive.__inaccessible> 
只要知道这种幕后处理手法,就能从类外访问私有方法,然而不应这样做。
>>> s._Secretive__inaccessible() 
Bet you can't see me ... 
总之,你无法禁止别人访问对象的私有方法和属性,但这种名称修改方式发出了强烈的信号,让他们不要这样做。
如果你不希望名称被修改,又想发出不要从外部修改属性或方法的信号,可用一个下划线打头。这虽然只是一种约定,但也有些作用。例如,from module import *不会导入以一个下划线打头的名称。例如,Java支持4种不同的私有程度。Python没有提供这样的支持,不过从某种程度上说,以一个和两个下划线打头相当于两种不同的私有程度。

总结:

第一个层面的封装:类就是麻袋,这本身就是一种封装

第二个层面的封装:类中定义私有的,只有类的内部使用,外部无法访问

第三个层面的封装:明确区分内外,内部的实现逻辑,外部无法知晓

并且为封装到内部的逻辑提供一个访问接口给外部使用(这才是真正的封装)

封装的好处

好处

  1. 在使用面向过程编程时,当需要对数据处理时,需要考虑用哪个模板中哪个函数来进行操作,但是当用面向对象编程时,因为已经将数据存储到了这个独立的空间中,这个独立的空间(即对象)中通过一个特殊的变量(__class__)能够获取到类(模板),而且这个类中的方法是有一定数量的,与此类无关的将不会出现在本类中,因此需要对数据处理时,可以很快速的定位到需要的方法是谁 这样更方便
  2. 全局变量是只能有1份的,多很多个函数需要多个备份时,往往需要利用其它的变量来进行储存;而通过封装 会将用来存储数据的这个变量 变为了对象中的一个“全局”变量,只要对象不一样那么这个变量就可以再有1份,所以这样更方便
  3. 代码划分更清晰

python基础(面向对象(封装、私有化封装))相关推荐

  1. python基础—面向对象

    python基础-面向对象 面向对象 面向过程VS面向对象 类和实例 实例变量和类变量 类的方法 实例方法 静态方法 类方法 面向对象的组合用法 封装.继承和多态 封装 继承 派生 方法的重写 继承注 ...

  2. python基础——面向对象的程序设计

    python基础--面向对象的程序设计 1 什么是面向对象的程序设计 面向过程的程序设计的核心是过程,过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优 ...

  3. [python基础] 面向对象——封装,继承

    面向对象 一.面向对象的基础知识 二.类和面向对象 三.封装 四.继承 (1).基本使用方法 (2).链表相加 (3).多继承 (4).私有属性与私有方法 一.面向对象的基础知识 1.面向对象 定义: ...

  4. 封装属性_「Python基础学习」之封装大法

    在程序设计中,封装是对具体对象的一种抽象,简单来说就是将某些部分隐藏起来,在程序外部看不到,这个看不到不是说人用眼睛看不到那个代码,其含义是其它的程序无法调用. 要了解封装,离不开"私有化& ...

  5. 学Python基础面向对象看这一篇文章就够了【全网首推】

    目录 面相对象基础语法 目标 01. dir 内置函数(知道) 02. 定义简单的类(只包含方法) 2.1 定义只包含方法的类 2.2 创建对象 2.3 第一个面向对象程序 03. 方法中的 self ...

  6. python基础----面向对象的程序设计(五个阶段、对小白的忠告、关于OOP常用术语)、类、对象...

    一.面向对象的软件开发有如下几个阶段                                              1.面向对象分析(object oriented analysis ,O ...

  7. Python基础-------面向对象二

    目录 一.封装 二.property装饰器 三.继承 四.多继承 五.方法的重写 super方法 一.封装 什么是封装 在日常中封装指的是将我们的物品包裹起来,不让看到其内部,具有保护的功能.在程序设 ...

  8. python基础 面向对象编程

    目录 面向对象编程 1.什么是面向对象编程? 面向过程编程思想 面向对象编程思想 2.什么是类?如何定义. 类: 对象 3.如何产生对象? 调用类时的事件: 4.对象属性的查找顺序: 5.类内部的函数 ...

  9. Python基础-面向对象编程

    本文完全转载自廖雪峰大神的教程: 面向对象编程 面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数 ...

  10. python基础--面向对象(一)

    面向对象的介绍 面向对象编程(Object Oriented Programming,OOP,面向对象程序设计) 举例: 1)解决菜鸟买电脑的故事 第一种方式: 1)在网上查找资料 2)根据自己预算和 ...

最新文章

  1. 170318 11:44:26 [ERROR] Can't start server: can't create PID file: No space left on device
  2. Crawler之Scrapy:Scrapy简介、安装、使用方法之详细攻略
  3. oracle命令未正确结束_详解Oracle数据库终止正在进行expdp导出数据的正确操作
  4. 算法系列之赫夫曼编码实战一【数据压缩、数据解压】
  5. 计算机英文文献博客,计算机专业外文文献论文翻译.docx
  6. es elasticsearch 几种常见查询场景 二次分组 java读取es的查询json文件
  7. Intel 64/x86_64/IA-32/x86处理器 - SIMD指令集 - MMX技术(6) - 移位与循环移位指令
  8. SVM与feature
  9. mysql8.0. linux二进制_linux下安装mysql8.0(二进制方式)
  10. 80% 的公司在招聘时都忽略的一个细节
  11. 正则表达式过滤联系方式,微信手机号QQ等
  12. android 宽度是多少dp,Android开发中dp、dpi、px的区别
  13. Android属于绑定服务特点是,Android P HIDL服务绑定模式与直通模式的分析 (原创)
  14. 微信小程序密码输入框
  15. 好玩的横版射击游戏介绍:Broforce武装原型 for mac
  16. Linux服务器集群LVS
  17. 【Linux】手把手教你搭建自己个人博客(boss版)
  18. Gated Mechanism For Attention Based Multimodal Sentiment Analysis基于注意力的多模式情感分析的门控机制——阅读笔记
  19. js 时间戳转换成正确的时间格式(本地时间早八小时问题解决)
  20. CAD文件怎么转换为DWF文件

热门文章

  1. Aspose.Words如何去掉自动生成的红字字体的表头
  2. 2022 极术通讯-安谋科技“周易”NPU教学开发平台亮相嵌入式系统周ESWEEK
  3. CHM文件打开空白是什么原因
  4. 工厂三兄弟之简单工厂模式(四)
  5. 买水果——hdu 2152
  6. 你听我说-HandyControl源码编译
  7. 河海大学20计算机考研复试回忆
  8. c# msiexec.exe卸载软件,cmd命令REG DELETE 清除注册表实例
  9. 寻找20以内某两个数相除,其结果离黄金分割点0.618最近
  10. LZ77算法原理及python实现