python 3 封装

从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小鱼,小虾,小王八,一起装进麻袋,然后把麻袋封上口子。照这种逻辑看,封装=‘隐藏’,这种理解是相当片面的。

先看如何隐藏

在python中用双下划线开头的方式将属性隐藏起来(设置成私有的)

其实这仅仅这是一种变形操作

类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式:

  1. class A:
  2.  
  3. __N=0 #类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N
  4.  
  5. def __init__(self):
  6.  
  7. self.__X=10 #变形为self._A__X
  8.  
  9. def __foo(self): #变形为_A__foo
  10.  
  11. print('from A')
  12.  
  13. def bar(self):
  14.  
  15. self.__foo() #只有在类内部才可以通过__foo的形式访问到.
  16.  
  17. A._A__N是可以访问到的,即这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形。

这种自动变形的特点:

  1. 类种定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。
  2. 这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。
  3. 在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下划线开头的属性在继承给子类时,子类是无法覆盖的。
  • 对于这一层面的封装(隐藏),我们需要在类中定义一个函数(接口函数)在它内部访问被隐藏的属性,然后外部就可以使用了

这种变形需要注意的问题是:

1.这种机制也没有真正意义上限制我们从外部直接访问属性,知道了雷鸣和属性名就可以拼出名字:_类名__属性,然后皆可以访问了,如a._A__N

2.变形的过程只在类的定义时放生一次,在定义后的赋值操作,不会变形

3.在继承中,父类如果不想让子类渡改自己的方法,可以将方法定义为私有的

python并不会真的阻止你访问私有的属性,模块也遵循这种约定,如果模块名以单下划线开头,那么from module import *时不能被导入,但是你from module import _private_module依然是可以导入的其实很多时候你去调用一个模块的功能时会遇到单下划线开头的(socket._socket,sys._home,sys._clear_type_cache),这些都是私有的,原则上是供内部调用的。作为外部也可以用,只过写出代码比较傻了,python要想与其他编程语言一样,严格控制属性的访问权限,只能借助内置方法如__getattr__

  1. #先看如何隐藏
  2.  
  3. class Foo:
  4.  
  5. __N=111111 #_Foo__N
  6.  
  7. def __init__(self,name):
  8.  
  9. self.__Name=name #self._Foo__Name=name
  10.  
  11. def __f1(self): #_Foo__f1
  12.  
  13. print('f1')
  14.  
  15. def f2(self):
  16.  
  17. self.__f1() #self._Foo__f1()
  18.  
  19. f=Foo('egon')
  20.  
  21. # print(f.__N)
  22.  
  23. # f.__f1()
  24.  
  25. # f.__Name
  26.  
  27. f.f2() #通f
  28.  
  29. #这种隐藏需要注意的问题:
  30.  
  31. #1:这种隐藏只是一种语法上变形操作,并不会将属性真正隐藏起来
  32.  
  33. print(Foo.__dict__)
  34.  
  35. print(f.__dict__)
  36.  
  37. print(f._Foo__Name)
  38.  
  39. print(f._Foo__N)
  40.  
  41. #2:这种语法级别的变形,是在类定义阶段发生的,并且只在类定义阶段发生
  42.  
  43. Foo.__x=123123123123123123123123123123123123123123
  44.  
  45. print(Foo.__dict__)
  46.  
  47. print(Foo.__x)
  48.  
  49. f.__x=123123123
  50.  
  51. print(f.__dict__)
  52.  
  53. print(f.__x)
  54.  
  55. #3:在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。
  56.  
  57. class Foo:
  58.  
  59. def __f1(self): #_Foo__f1
  60.  
  61. print('Foo.f1')
  62.  
  63. def f2(self):
  64.  
  65. self.__f1() #self._Foo_f1
  66.  
  67. class Bar(Foo):
  68.  
  69. def __f1(self): #_Bar__f1
  70.  
  71. print('Bar.f1')
  72.  
  73. b=Bar()
  74.  
  75. b.f2()
  76.  
  77. #封装不是单纯意义的隐藏
  78.  
  79. #1:封装数据属性:将属性隐藏起来,然后对外提供访问属性的接口,关键是我们在接口内定制一些控制逻辑从而严格控制使用对数据属性的使用
  80.  
  81. class People:
  82.  
  83. def __init__(self,name,age):
  84.  
  85. if not isinstance(name,str):
  86.  
  87. raise TypeError('%s must be str' %name)
  88.  
  89. if not isinstance(age,int):
  90.  
  91. raise TypeError('%s must be int' %age)
  92.  
  93. self.__Name=name
  94.  
  95. self.__Age=age
  96.  
  97. def tell_info(self):
  98.  
  99. print('<名字:%s 年龄:%s>' %(self.__Name,self.__Age))
  100.  
  101. def set_info(self,x,y):
  102.  
  103. if not isinstance(x,str):
  104.  
  105. raise TypeError('%s must be str' %x)
  106.  
  107. if not isinstance(y,int):
  108.  
  109. raise TypeError('%s must be int' %y)
  110.  
  111. self.__Name=x
  112.  
  113. self.__Age=y
  114.  
  115. p=People('egon',18)
  116.  
  117. p.tell_info()
  118.  
  119. # p.set_info('Egon','19')
  120.  
  121. p.set_info('Egon',19)
  122.  
  123. p.tell_info()
  124.  
  125. #2:封装函数属性:为了隔离复杂度
  126.  
  127. #取款是功能,而这个功能有很多功能组成:插卡、密码认证、输入金额、打印账单、取钱
  128.  
  129. #对使用者来说,只需要知道取款这个功能即可,其余功能我们都可以隐藏起来,很明显这么做
  130.  
  131. #隔离了复杂度,同时也提升了安全性
  132.  
  133. class ATM:
  134.  
  135. def __card(self):
  136.  
  137. print('插卡')
  138.  
  139. def __auth(self):
  140.  
  141. print('用户认证')
  142.  
  143. def __input(self):
  144.  
  145. print('输入取款金额')
  146.  
  147. def __print_bill(self):
  148.  
  149. print('打印账单')
  150.  
  151. def __take_money(self):
  152.  
  153. print('取款')
  154.  
  155. def withdraw(self):
  156.  
  157. self.__card()
  158.  
  159. self.__auth()
  160.  
  161. self.__input()
  162.  
  163. self.__print_bill()
  164.  
  165. self.__take_money()
  166.  
  167. a=ATM()
  168.  
  169. a.withdraw()
  170. # _x=123

示例代码

python 3 封装的更多相关文章

  1. 将Python脚本封装成exe可执行文件 转

    将Python脚本封装成exe可执行文件 http://www.cnblogs.com/renzo/archive/2012/01/01/2309260.html  cx_freeze是用来将 Pyt ...

  2. python继承——封装

    python继承--封装 1 为什么要封装 封装数据的主要原因是:保护隐私 封装方法的主要原因是:隔离复杂度 2 封装分为两个层面 第一个层面的封装(什么都不用做):创建类和对象会分别创建二者的名称空 ...

  3. 【转】Python基础-封装与扩展、静态方法和类方法

    [转]Python基础-封装与扩展.静态方法和类方法 一.封装与扩展 封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码:而外部使用者只知道一个接口(函数),只要接口(函数 ...

  4. python面向对象-封装-property-接口-抽象-鸭子类型-03

    封装 什么是封装: # 将复杂的丑陋的隐私的细节隐藏到内部,对外提供简单的使用接口 或 # 对外隐藏内部实现细节,并提供访问的接口 为什么需要封装 1.为了保证关键数据的安全性 2.对外部隐藏内部的实 ...

  5. python学习笔记:安装boost python库以及使用boost.python库封装

    学习是一个累积的过程.在这个过程中,我们不仅要学习新的知识,还需要将以前学到的知识进行回顾总结. 前面讲述了Python使用ctypes直接调用动态库和使用Python的C语言API封装C函数, C+ ...

  6. python文件封装成*.exe

    python文件封装成*.exe文件(单文件和多文件) 环境:win10 64位 python3.7 原文: https://www.cnblogs.com/jackzz/p/9431923.html ...

  7. 第7.9节 案例详解:Python类封装

    上节介绍了Python中类的封装机制,本节结合一个具体例子进行详细说明. 我们定义一个Person类,其内部有姓名.年龄和类型三个实例变量,并定义了相关的存取方法: class Person():   ...

  8. python面向对象(封装,继承,多态)

    python面向对象(封装,继承,多态) 学习完本篇,你将会深入掌握 如何封装一个优雅的借口 python是如何实现继承 python的多态 封装 含义: 1.把对象的属性和方法结合成一个独立的单位, ...

  9. 利用PyInstaller将python代码封装成EXE(亲测可用)

    有些不能成功,有些不全的,下面总结一下,给自己以后看看.   1下载PyInstaller..去官网下载http://www.pyinstaller.org/(我下载的版本)   2不需要安装,解压即 ...

随机推荐

  1. 如何验证cname,MX,spf记录是否生效?

    创建域名邮箱时,对域名做完相应设置后,在域名邮箱设置里点击“设置完成并提交验证”来等待验证所有权和MX记录设置的正确性.但同时也可以通过下面的方法确认设置是否成功和正确: 一.验证CNAME记录的方法 ...

  2. 模拟和数字低通滤波器的MATLAB实现

    低通滤波器参数:Fs=8000,fp=2500,fs=3500,Rp=1dB,As=30dB,其他滤波器可以通过与低通之间的映射关系实现. %%模拟滤波器 %巴特沃斯——滤波器设计 wp=2*pi*2 ...

  3. Gmail收不到邮件咋办?

    http://www.ipip.net/ping.php 分别输入 imap.gmail.com pop.gmail.com smtp.gmail.com 选择  国外 , 然后点ping,找到对应的 ...

  4. CIA 读书笔记

    对此书的评价只有八个字:粗制滥造,到处粘贴. 对于通过表情识别人情绪的教程,最好要有图,图很重要,也最好有案例.

  5. Hadoop环境搭建2_hadoop安装和运行环境

    1 运行模式: 单机模式(standalone):  单机模式是Hadoop的默认模式.当首次解压Hadoop的源码包时,Hadoop无法了解硬件安装环境,便保守地选择了最小配置.在这种默认模式下所有 ...

  6. SPSS统计功能与模块对照表

    SPSS统计功能 - 应用速查表第一列为统计方法,中间为统计功能,最后一列为所在模块 1 ANOVA Models(单因素方差分析:简单因子) : 摘要 描述 方差 轮廓 - SPSS Base 2 ...

  7. android 二维码制作,显示到UI,并保存SD卡,拿来就能用!!

    转载请注明出处:王亟亟的大牛之路 如今二维码已经渗透了我们的生活.各种扫码关注啊.扫码下载的,今天上一个依据输入内容生成二维码的功能. 包结构: 界面截图: 功能:输入网址–>生成图片–> ...

  8. Matrix4x4矩阵 api

    Matrix4x4 矩阵api介绍 Namespace: UnityEngine Description 描述 A standard 4×4 transformation matrix. 一个标准的4 ...

  9. 解决Class 'swoole_server' not found

    1.看下cli模式是否可以正常工作,命令行下运行 php -r "echo php_sapi_name();" 这条命令就是在cli模式运行php语句,php -r就是run一条p ...

  10. 将PHP 5.3.3 (cli)升级到PHP 5.6.31 (cli)

    centos默认系统安装的是php5.3 [root@sz-local1 scripts]# rpm -qa |grep phpphp-pdo-5.3.3-47.el6.x86_64php-mysql ...