1. 1.封装之如何实现属性的隐藏
    封装: __x=1 # 把数据属性隐藏 (如何实现隐藏) 类定义阶段 __开头发生了变形 __x --> _A__x
    特点:
    1.在类外部无法直接:obj.__AttrName
    2.在类内部是可以直接使用:obj.__AttrName # 为什么会这样?python 如何实现的 !类定义阶段已经变形 #__x --> _A__x #self._A_foo()
    3.子类无法覆盖父类__开头的属性 它两根本不是一个名字 #_Foo__func #_Bar__func
    总结:
    这种变形需要注意的问题:
    1.这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如a._A__N eg:print(A._A__x)
    2.变形的过程只在类的定义时发生一次,在定义后的赋值操作,不会变形 eg: b.__age=18 {'_B__name': 'alice', '__age': 18}
    3.在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的 eg: def __foo(self): #_A__foo
  1. # class A:
  2. # __x=1 # 把数据属性隐藏 _A__x
  3. #
  4. # def __init__(self,name):
  5. # self.__name=name # _A__name
  6. #
  7. # def __foo(self): # 把函数属性隐藏 def _A__foo(self)
  8. # print('run foo')
  9. #
  10. # def bar(self):
  11. # self.__foo() #self._A_foo() 定义阶段已经变了
  12. # print('from bar')
  13.  
  14. # print(A.__dict__)
  15. # {'__module__': '__main__', '_A__x': 1, '__init__': <function A.__init__ at 0x0000017AC92B0B70>, '_A__foo': <function A.__foo at 0x0000017AC92B0BF8>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
  16. # 类定义阶段 __开头发生了变形 __x --> _A__x
  17.  
  18. # print(A.__x)
  19. # print(A._A__x)
  20. # print(A.__foo)
  21. # print(A._A__foo)
  22. # a=A('alice')
  23. # print(a.__dict__)
  24. # {'_A__name': 'alice'}
  25. # print(a.__name)
  26. # print(a._A__name)
  27. # a.bar()
  28.  
  29. # ---------------------------------------------
  30. # class Foo:
  31. # def __func(self): #_Foo__func
  32. # print('from foo')
  33. #
  34. # class Bar(Foo):
  35. # def __func(self): #_Bar__func
  36. # print('from bar')
  37.  
  38. # b=Bar()
  39. # b.func() # 子类把父类 重名的给覆盖掉了
  40.  
  41. # ---------------------------------------------
  42. # class B:
  43. # __x=1
  44. #
  45. # def __init__(self,name):
  46. # self.__name=name
  47.  
  48. # # print(B._B__x) # 一般不要这么做!py不让你这么干了
  49. # B.__y=2 # 类定义完之后不会发生变形
  50. # # print(B.__dict__)
  51. # # {'__module__': '__main__', '_B__x': 1, '__init__': <function B.__init__ at 0x00000180405A0B70>, '__dict__': <attribute '__dict__' of 'B' objects>, '__weakref__': <attribute '__weakref__' of 'B' objects>, '__doc__': None, '__y': 2}
  52. #
  53. # b=B('alice')
  54. # print(b.__dict__) # {'_B__name': 'alice'}
  55. #
  56. # b.__age=18
  57. # print(b.__dict__) #{'_B__name': 'alice', '__age': 18}
  58.  
  59. # ---------------------------------------------
  60. # class A:
  61. # def foo(self):
  62. # print('A.foo')
  63. #
  64. # def bar(self):
  65. # print('A.bar')
  66. # self.foo() #b.foo
  67. #
  68. # class B(A):
  69. # def foo(self):
  70. # print('B.foo')
  71. #
  72. # b=B()
  73. # b.bar()
  74.  
  75. # ---------------------------------------------
  76. class A:
  77. def __foo(self): #_A__foo
  78. print('A.foo')
  79.  
  80. def bar(self):
  81. print('A.bar')
  82. self.__foo() #self._A__foo() # 只调自己类的方法 定义时就已经确定好的!
  83.  
  84. class B(A):
  85. def __foo(self): #_B__foo
  86. print('B.foo')
  87.  
  88. b=B()
  89. b.bar()
  1. 2.封装的意义
    封装数据属性目的: (封装不是单纯意义上的隐藏)
    明确的区分内外,控制外部对隐藏的属性的操作行为
  2.  
  3. 封装方法属性目的:
    隔离复杂度 # a=ATM() a.withdraw()
  1. # class People:
  2. # def __init__(self,name,age):
  3. # self.__name=name
  4. # self.__age=age
  5. #
  6. # def tell_info(self): # 接口 设定规则
  7. # print('Name:<%s> Age:<%s>'%(self.__name,self.__age))
  8. #
  9. # def set_info(self,name,age): # 接口 间接的修改 设定规则
  10. # if not isinstance(name,str):
  11. # print('名字必须是字符串类型')
  12. # return
  13. # if not isinstance(age,int):
  14. # print('年龄必须是数字类型')
  15. # return
  16. # self.__name=name
  17. # self.__age=age
  18. #
  19. # p=People('alice','18')
  20. # p.tell_info()
  21.  
  22. # p.set_info('alex',38)
  23. # p.tell_info()
  24.  
  25. # p.set_info('alex','38')
  26. # p.tell_info()
  27.  
  28. # -------------------------------------------------------
  29. class ATM:
  30. def __card(self): # 复杂的流程 给隐藏起来了 外部没必要关心
  31. print('插卡')
  32. def __auth(self):
  33. print('用户认证')
  34. def __input(self):
  35. print('输入取款金额')
  36. def __print_bill(self):
  37. print('打印账单')
  38. def __take_money(self):
  39. print('取款')
  40.  
  41. def withdraw(self): # 只有这个是用户 关心的
  42. self.__card()
  43. self.__auth()
  44. self.__input()
  45. self.__print_bill()
  46. self.__take_money()
  47.  
  48. a=ATM()
  49. a.withdraw()
  1. 3.封装与扩展性
    面向对象:可扩展性高
    面向对象三大特性:继承 多态 封装
    封装的扩展性:
    def tell_area(self): # 对使用者来说 不用改变 方式 开发者在类里面修改
  1. class Room:
  2. def __init__(self,name,owner,weight,length,height):
  3. self.name=name
  4. self.owner=owner
  5.  
  6. self.__weight=weight
  7. self.__length=length
  8. self.__height=height
  9.  
  10. def tell_area(self): # 对使用者来说 不用改变 方式
  11. return self.__weight * self.__length * self.__height
  12.  
  13. r=Room('卫生间','alex',10,10,10)
  14. print(r.tell_area())
  1. 4.property的使用
    BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)
    成人的BMI数值:
    过轻:低于18.5
    正常:18.5-23.9
    过重:24-27
    肥胖:28-32
    非常肥胖, 高于32
    体质指数(BMI)=体重(kg)÷身高^2m
    EX70kg÷(1.75×1.75)=22.86
    -------------------------------
    property :
    @property
    def bmi(self): 必须有个返回值
    print(p.bmi) 可以使 函数属性 伪装成 数据属性 bmi 是名词
  2.  
  3. p.bmi=23 # 不能赋值 can't set attribute bmi 实质是个方法
  4.  
  5. 总结:通过计算得来的方法 可以通过@property 伪装成数据属性
    @property 查看 必须有返回值
    @name.setter 修改
    @name.deleter 删除
  1. # class People:
  2. # def __init__(self,name,weight,height):
  3. # self.name=name
  4. # self.weight=weight
  5. # self.height=height
  6. #
  7. # @property
  8. # def bmi(self): # 必须要有个返回值
  9. # return self.weight / (self.height ** 2)
  10. #
  11. # p=People('egon',75,1.81)
  12. # p.bmi=p.weight / (p.height ** 2)
  13. # print(p.bmi)
  14.  
  15. # print(p.bmi()) # 函数 是 去做什么! 是动词 对于使用者 产生误解 调了一个动词
  16.  
  17. # print(p.bmi) # 使用者可以像 访问数据属性 那样 访问 函数属性
  18. # p.height=1.82
  19. # print(p.bmi)
  20. # p.bmi=23 # 不能赋值 can't set attribute bmi 实质是个方法
  21.  
  22. # ------------------------------------------------------------
  23. class People:
  24. def __init__(self,name):
  25. self.__name=name
  26.  
  27. @property # 查看
  28. def name(self):
  29. # print('getter')
  30. return self.__name
  31.  
  32. @name.setter # 修改 # 前提是 一定被装饰过 property
  33. def name(self,val):
  34. # print('setter',val)
  35. if not isinstance(val,str):
  36. print('名字必须是字符串')
  37. return
  38. self.__name=val
  39.  
  40. @name.deleter # 删除
  41. def name(self):
  42. # print('deleter')
  43. print('不允许删除')
  44.  
  45. p=People('alice')
  46. # print(p.name)
  47.  
  48. # p.name='alex'
  49. # print(p.name)
  50.  
  51. del p.name
  1.  

面向对象 - 1.封装之如何实现属性的隐藏/2.封装的意义/3.封装与扩展性/4.property的使用的更多相关文章

  1. 面向对象编程(封装、封装的意义、封装与扩展性、@property)

    1.封装之如何实现属性的隐藏 封装: __x=1 # 把数据属性隐藏 (如何实现隐藏) 类定义阶段 __开头发生了变形 __x --> _A__x特点: 1.在类外部无法直接:obj.__Att ...

  2. python进阶01 面向对象、类、实例、属性封装、实例方法

    python进阶01 面向对象.类.实例.属性封装.实例方法 一.面向对象 1.什么是对象 #一切皆对象,可以简单地将“对象”理解为“某个东西” #“对象”之所以称之为对象,是因为它具有属于它自己的“ ...

  3. python 3全栈开发-面向对象之绑定方法(classmethod与staticmethod的区别)、多态、封装的特性property

    一.面向对象绑定方法 一.类中定义的函数分成两大类 1.绑定方法(绑定给谁,谁来调用就自动将它本身当作第一个参数传入): 1. 绑定到类的方法:用classmethod装饰器装饰的方法. 为类量身定制 ...

  4. Java:【面向对象:类的定义,静态变量,成员变量,构造函数,封装与私有,this】

    本文内容: 什么是面对对象 类的定义与对象实例化 成员变量 成员变量的有效范围 成员变量的赋值 静态变量.方法与实例变量.方法 构造函数 封装与私有 this关键字 注:函数和方法是一样东西.[由于我 ...

  5. Python之路(第二十二篇) 面向对象初级:概念、类属性

    一.面向对象概念 1. "面向对象(OOP)"是什么? 简单点说,“面向对象”是一种编程范式,而编程范式是按照不同的编程特点总结出来的编程方式.俗话说,条条大路通罗马,也就说我们使 ...

  6. 2.Python封装练习及私有属性

    面向对象三大特性 封装:根据职责将属性和方法封装到一个抽象的类中 继承:实现代码的重用,相同代码不需要重复的编写 1.单继承 2.多继承 多态:不同的对象调用相同的方法,产生不同的执行结果,增加代码的 ...

  7. 04-OC属性的使用、自动释放池、封装和继承

    目录: 一.IOS6声明式属性的使用 二.autoreleasepool自动释放池 三.封装.继承 回到顶部 一.IOS6声明式属性的使用 注:声明式属性默认情况下,并没有解决内存问题, 当使用@pr ...

  8. python基础----封装、封装与扩展性

    从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小猫,小狗,小王八,还有egon和alex一起装进麻袋,然后把麻袋封上口子.但其实这种理解相当片面 首先我们要了解 要封装什么 你钱包的有多少钱(数 ...

  9. python之封装与扩展性

    1.封装与扩展性 封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用的代码:而外部使用者只知道一个接口(函数),只要接口(函数)名,参数不变,使用者的代码永远无需改变.这就提供了一 ...

随机推荐

  1. Java序列化与反序列化学习(二):序列化接口说明

    一.序列化类实现Serializable接口 Serializable接口没有方法,更像是个标记.有了这个标记的Class就能被序列化机制处理. ObjectOutputStream只能对Serial ...

  2. poj 1475 Pushing Boxes 推箱子(双bfs)

    题目链接:http://poj.org/problem?id=1475 一组测试数据: 7 3 ### .T. .S. #B# ... ... ... 结果: //解题思路:先判断盒子的四周是不是有空 ...

  3. 【Objective-C】03-第一个OC程序

    一.打开Xcode,新建Xcode项目 二.选择最简单的命令行项目 因为我们只是学习OC语法,还未正式进入iOS开发,所以选择命令行项目即可 三.输入项目名称,选择Foundation框架进行创建项目 ...

  4. java -jar命令

    1.用eclipse的export导出jar包后,打开jar中的MANIFEST.MS文件,修改如下: 2.然后在命令行中输入命令:java -jar aa.jar即可.

  5. javascript深入理解js闭包【手动加精】

    http://www.jb51.net/article/24101.htm 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.   一.变量的作用 ...

  6. 由Python的一个小例子想到的

    习题: L = [1,2] L.append(L) Print L 问,结果是什么. 结果是,[1,2,[...]] 这是什么意思呢?就是说[...]表示的对[1,2]的无限循环.这一点是在C#等静态 ...

  7. Unix系统编程()main函数的命令行参数

    命令行参数输入双引号是什么效果? 好像可以去空格化.

  8. A protocol error occurred. Change of username or service not allowed: (root,ssh-connection) -> (zoujiaqing,ssh-connection)

    SecureCRT ssh 客户端连接失败: The server has disconnected with an error.  Server message reads: A protocol ...

  9. spring+mybatis+javafx

    @Service用于标注业务层组件 @Controller用于标注控制层组件(如struts中的action) @Repository用于标注数据访问组件,即DAO组件. @Component泛指组件 ...

  10. 长尾分布,重尾分布(Heavy-tailed Distribution)

    Zipf分布: Zipf分布是一种符合长尾的分布: 就是指尾巴很长的分布.那么尾巴很长很厚的分布有什么特殊的呢?有两方面:一方面,这种分布会使得你的采样不准,估值不准,因为尾部占了很大部分.另一方面, ...