封装:

【封装】
         隐藏对象的属性和实现细节,仅对外提供公共访问方式。
【好处】 
1. 将变化隔离; 
2. 便于使用;
3. 提高复用性; 
4. 提高安全性;
【封装原则】
      1. 将不需要对外提供的内容都隐藏起来;
      2. 把属性都隐藏,提供公共方法对其访问。

广义封装:
把一些属性和方法放到类里,这本身就是一种封装

  1. class Foo:
  2.   role = class
  3.   def func(self):
  4.     pass

狭义上的:
把属性和方法藏在类里,只能在类内部调用,不能在外部使用

  1. class Dog:
  2. __role = 'dog' #私有的静态属性 (相当于内部自动变成 _Dog__role)
  3. def __discount(self): #私有的方法
  4. print('in __func')
  5.  
  6. def price(self):
  7. self.__discount() #私有的对象属性
  8.  
  9. def func(self):
  10. print(Dog.__role) #内部可以调用私有属性
  11.  
  12. print(Dog.__dict__)
  13. print(Dog._Dog__role) #知道有这种查看方法就行,一般不要用,这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形

  14. {'__module__': '__main__', '_Dog__role': 'dog',.......} _Dog__role相当于内部外运加上了(_类名)
  15. #dog
  16. 类似加了一层密码
  17. ------------------------
  18. d = Dog()
  19. d.func() #内部调用
  20. #dog

==============================
在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的

  1. #把fa定义成私有的,即__fa
  2. class A:
  3. def __fa(self): #在定义时就变形为_A__fa
  4. print('from A')
  5. def test(self):
  6. self.__fa() #这个self.__fa() 实际上是self._A__fa() 所以调用的是A内部的def__fa()
  7.  
  8. class B(A):
  9. def __fa(self):
  10. print('from B')
  11.  
  12. b=B()
  13. b.test()
  14. from A

================

私有的不能被继承:

  1. class A:
  2. def __fa(self): #在定义时就变形为_A__fa
  3. print('from A')
  4.  
  5. class B(A):
  6. def __init__(self):
  7. self.__fa() # 实际上是self._B__fa()
  8.  
  9. b=B()

执行会报错:AttributeError: 'B' object has no attribute '_B__fa'

==============

狭义封装小结:
私有属性: 静态属性,方法,对象属性 3种
内部能调用,外部不能
不能被继承
当有一个属性,不想被外部使用,也不想被子类继承,只想内部使用,就定义成私有的
========================================================

@property 伪装

property: 伪装 (__变量 配合起来就很强大了)

@property: 把一个方法伪装成一个属性

1.属性的值是方法的返回值
2.这个方法就不能有参数了

--------------
例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)

成人的BMI数值:
过轻:低于18.5
正常:18.5-23.9
过重:24-27
肥胖:28-32
非常肥胖, 高于32
  体质指数(BMI)=体重(kg)÷身高^2(m)
  EX:70kg÷(1.75×1.75)=22.86

  1. class Person:
  2. def __init__(self,name,height,weight):
  3. self.name = name
  4. self.height = height
  5. self.__weight = weight
  6.  
  7. @property # 只是伪装作用
  8. def bmi(self): # 方法不能有参数
  9. return self.__weight / (self.height ** 2)
  10.  
  11. kit = Person('kitty',1.75,85)
  12. print(kit.bmi) #kit.bmi 相当于 kit.bmi()
  13. #27.755

如果 print(kit.bmi()) 就相当于 print(27.755()) 报错:TypeError: 'float' object is not callable
--------------------------------------------------------------------------------------------------------------------------

  1. class Goods:
  2. __discount = 0.8 #静态属性
  3. def __init__(self,name,price):
  4. self.__name = name
  5. self.__price = price #原价
  6. @property
  7. def name(self):
  8. return self.__name
  9.  
  10. @property
  11. def price(self): #折后价
  12. return self.__price * Goods.__discount
  13.  
  14. apple = Goods('苹果',10)
  15. print(apple.price)
  16. apple.price = 100 报错:AttributeError: can't set attribute (安全:属性不能随便修改)
  17. print(apple.price)
  18. # __私有+property
  19. #让对象的属性变得更安全了  

-------------------------------------------------------------------------------

property    setter

例题三:

修改价格,加了一个if判断

  1. class Goods:
  2. __discount = 0.8 #静态属性
  3. def __init__(self,name,price):
  4. self.__name = name #将所有的数据属性都隐藏起来
  5. self.__price = price #原价
  6. @property
  7. def name(self):
  8. return self.__name #obj.name访问的是self.__name(这也是真实值的存放位置)
  9.  
  10. @name.setter setter的位置只能传一个参数 obj.name = 'apple'
  11. def name(self,new_name):
  12. self.__name = new_name
  13.  
  14. @property
  15. def price(self): #折后价 #在设定值之前进行类型检查
  16. return self.__price * Goods.__discount #通过类型检查后,将值value存放到真实的位置self.__name
  17.  
  18. @price.setter #绕了一大圈,就为了修改属性这个简单的操作,目的是 加个 if 判断
  19. def price(self,new_price): #修改原价
  20. if type(new_price) is int: #必须是int类型
  21. self.__price = new_price
  22.  
  23. @price.deleter
  24. def price(self):
  25. raise TypeError('不能修改') #主动触发异常
  26.  
  27. apple = Goods('苹果',10)
  28. print(apple.price)
  29. #8.0
  30. apple.price = 100 #settrt 改变的是对象的属性
  31. print(apple.price) #property
  32. #80.0
  33. -----------
  34. banana = Goods('香蕉',10)
  35. print(banana.price)
  36. #16.0
  37. print(apple.price) #创建新对象,苹果的价格没有变化
  38. #80.0
  39. -------------
  40. del apple.price # TypeError: 不能修改

封装:

  @property @price.setter @price.deleter
  1.方法伪装成数据属性 (例题一:print(kit.bmi) )
  2.__私有+property, 让对象的属性变得更安全了 (例题二:修改价格,报错)
  3.获取到的对象的值可以进行一些加工 (例题三:修改价格,成功, 但是只能传一个参数)
  4.修改对象的值的同时可以进行一些验证 (例题三:判断输入的是否是数字)
========================================================

1.如果只用@property, 属性就是固定的了,不能更改了
2.为什么setter 呢?
就是每次操作,都可以 if判断, raise主动触发异常 等等操作
让对象 的属性变得更安全了
-------------------------------------------------------------------------------

=================================

  1. class Foo:
  2. # @property
  3. def AAA(self):
  4. print('get的时候运行我啊')
  5.  
  6. @AAA.setter # 如果没有@property 报错:AttributeError: 'function' object has no attribute 'setter'
  7. def AAA(self, value):
  8. print('set的时候运行我啊')
  9.  
  10. @AAA.deleter
  11. def AAA(self):
  12. print('delete的时候运行我啊')
  13.  
  14. # 只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter
  15. f1 = Foo()
  16. f1.AAA # property
  17. f1.AAA = 'aaa' # setter
  18. del f1.AAA # deleter
  19. # get的时候运行我啊
  20. # set的时候运行我啊
  21. # delete的时候运行我啊

============================

类方法:@classmethod

  1. class Goods:
  2. __discount = 0.8 # 想把类的静态属性改了
  3.  
  4. def change_discount(self,new_discount):
  5. self.__discount = new_discount
  6.  
  7. def get_discount(self):
  8. return self.__discount
  9.  
  10. # Goods._Goods__discount = 1 #不能用这个
  11. apple = Goods()
  12. print(Goods._Goods__discount) # 0.8
  13. apple.change_discount(0.75)
  14. print(apple.get_discount()) # 0.75 类的实例对象修改的是对象自己的属性
  15. print(Goods._Goods__discount) # 0.8 但是类的静态变量没变

----------------------

  1. class Goods:
  2. __discount = 0.8
  3.  
  4. @classmethod # 类方法
  5. def change_discount(cls, new_discount): # cls 不需要self参数,直接传 类
  6. cls.__discount = new_discount
  7.  
  8. @classmethod
  9. def get_discount(cls):
  10. return cls.__discount
  11.  
  12. # 不需要创建对象
  13. print(Goods.get_discount())
  14. # 0.8
  15. Goods.change_discount(0.75)
  16. print(Goods.get_discount()) # 类的属性改变了
  17. # 0.75

============================
类方法

调用:不需要实例化 直接用类名调用就好
定义:不用接受self参数,默认传cls,cls就代表当前方法所在的类
什么时候用类方法?
需要使用静态变量 且 不需要和对象相关的任何操作的时候

=========================

静态方法:@staticmethod

先来看一段代码

  1. class A:
  2. def func(): # 没有self, 有红色下划线 (这已经是一个静态方法了)
  3. print(123)
  4.  
  5. A.func()
  6. # 123 #也不报错 但是不符合规范

定义一个静态方法,要使用@staticmethon

  1. class A:
  2. @staticmethod #如果要定义一个不传self参数的方法,要加@staticmethon 这样就不报错了
  3. def func(name,age): #静态方法
  4. print(name,age)
  5. A.func('kitty',18)
  6. #'kitty',18

和普通的调用函数没有什么区别了

========================

静态方法:
如果这个方法 ,既不需要操作静态变量,也不需要使用对象相关的操作,就用静态方法
---------------------------------------------------------------------------------

面向对象编程:

什么是面向对象编程?
面向对象是一种思想,但是它也有一种规范,假如整篇用面向对象编程,那么整个程序里面不可以写除了类以外的其他东西,不可以定义函数,所有的函数必须定义到类里面.

staticmethod--专门为面向对象编程提供的一个方法
它完全可以当做普通函数去用,只不过这个函数要通过类名.函数名调用
其他 传参 返回值 完全没有区别

======================================

  1. class A:
  2. @staticmethod
  3. def func1(name): # 静态方法
  4. print(123)
  5.  
  6. @classmethod
  7. def func2(cls): # 类态方法
  8. print(123)
  9.  
  10. def func3(self): pass
  11.  
  12. a = A()
  13. print(a.func1) # 静态方法
  14. # <function A.func1 at 0x00000000023188C8>
  15. print(a.func2) # 类方法 : 绑定到A类的func
  16. # <bound method A.func2 of <class '__main__.A'>>
  17. print(a.func3) # 普通方法:绑定到A类对象的func
  18. # <bound method A.func3 of <__main__.A object at 0x000000000231B160>>

类里面,一共可以定义三种方法:

  1. 普通方法: self  对象调用 (方法里面用到对象相关的变量)
  2. 类方法: @classmethod      类调用 (方法里面用到类的静态变量或静态方法)
  3. 静态方法: @staticmethod   类调用 (方法里面啥都没有用到)

(  类方法和静态方法 对象也可以调用,但没必要为了调用 去创建一个对象)

=================================================

Python()- 面向对象三大特性----封装的更多相关文章

  1. python 面向对象三大特性(封装 多态 继承)

    今天我们来学习一种新的编程方式:面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)注:Java和C#来说只支持面向对象编程,而python比较灵活即支持面 ...

  2. Python面向对象三大特性(封装、继承、多态)

    封装 类中把某些属性和方法隐藏起来,或者定义为私有,只在类的内部使用,在类的外部无法访问,或者留下少量的接口(函数)供外部访问:从上一篇文章中的私有属性与私有方法中的代码体现了该特性. class m ...

  3. [.net 面向对象编程基础] (11) 面向对象三大特性——封装

    [.net 面向对象编程基础] (11) 面向对象三大特性——封装 我们的课题是面向对象编程,前面主要介绍了面向对象的基础知识,而从这里开始才是面向对象的核心部分,即 面向对象的三大特性:封装.继承. ...

  4. python 面向对象(三大特性)

    python 面向对象(初级) (思维导图 ↑↑↑↑↑) 概述: 面向过程:根据业务逻辑从上到下垒代码. 函数式:将某功能代码封装至函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类 ...

  5. python面向对象三大特性

    面向对象的三大特性: 封装.继承和多态 一.封装 封装,顾名思义就是将内容封装到某个地方,以后可以直接调用被封装到某处的内容. - 将内容封装到某处 - 从某处调用被封装的内容 第一步,将内容封装到某 ...

  6. python面向对象-三大特性

    python面向对象编程三大特性 小结:前面我们说完了类和对象的关系,相信对类和对象的理解更加透彻..让我们一起去研究面向对象的三大特性吧.... 继承 1.什么继承? 在程序中继承就是事物之间的所属 ...

  7. python面向对象三大特性之一封装

    一.什么是封装 在程序设计中,封装(Encapsulation)是对具体对象的一种抽象,即将某些部分隐藏起来,在程序外部看不到,其 含义是其他程序无法调用. 要了解封装,离不开“私有化”,就是将类或者 ...

  8. Python入门-面向对象三大特性-封装

    一.封装 封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容. 所以,在使用面向对象的封装特性时,需要: 将内容封装到某处 从某处调用被封装的内容 第一步:将内容封装到某处 sel ...

  9. python面向对象三大特性之一继承、多态、封装

    继承,即在定义一个类时,以另一个类为参数,则称这个新定义的类继承了参数类,父类又称为基类. 单继承表示只继承一个类,多继承表示继承多个类. class parent1: pass class pare ...

随机推荐

  1. 【学习笔记】深入理解js原型和闭包(14)——从【自由变量】到【作用域链】

    先解释一下什么是“自由变量”. 在A作用域中使用的变量x,却没有在A作用域中声明(即在其他作用域中声明的),对于A作用域来说,x就是一个自由变量.如下图 如上程序中,在调用fn()函数时,函数体中第6 ...

  2. String.format()【示例详解】

    String.format()[示例详解] 整理者:Vashon 前言: String.format 作为文本处理工具,为我们提供强大而丰富的字符串格式化功能,为了不止步于简单调用 String.fo ...

  3. 两个已排序数组的合并-C语言

    最近在纸上写一个已排序数组的合并时,花了超过预期的时间.仔细想想,这种要放到毕业找工作那会两下就出来了,原因还在于工作后对基础没有重视,疏于练习. 说开一点,现在搜索引擎的发达确实给问题的解决带来了便 ...

  4. sql 删除重复数据

    DELETE a FROM tbBuilding a WHERE EXISTS (SELECT 1 FROM tbBuilding b WHERE b.Province = a.Province AN ...

  5. 4.03 使用NULL代替默认值

    问题:在一个定义了默认值的列插入数据,并且需要不管该列的默认值是什么,都将该列值设为NULL.考虑一下下面的表: create table D (id interger default 0, foo ...

  6. Django 路由 —— Djangon如何处理一个请求

    Django URL路由概述 一个干净优雅的URL方案是高质量Web应用程序中的一个重要细则Django可以让你设计URL,无论你想要什么,没有框剪限制要为应用程序设计URL,您可以非正式地创建一个名 ...

  7. VS2015提示:未安装Style的Visual Studio语言支持,代码编辑Intellisense将不可用。服务器控件的标记Intellisense可能不起作用

    一.问题 最近在VS2015打开文件,提示未安装Style的Visual Studio语言支持,代码编辑Intellisense将不可用.服务器控件的标记Intellisense可能不起作用. Int ...

  8. Gameia

    F - Gameia HDU - 6105   Alice and Bob are playing a game called 'Gameia ? Gameia !'. The game goes l ...

  9. SVN 初级教程

    版本控制器:SVN 1.SVN 作用? 备份.代码还原.协同修改.多版本项目文件管理.追溯问题代码的编写人和编写时间.权限控制等. 2.版本控制简介 2.1 版本控制[Revision control ...

  10. 自制操作系统小样例——参考部分linux0.11内核源码

    详细代码戳这里. 一.启动引导 采用软件grub2进行引导,基于规范multiboot2进行启动引导加载.multiboot2的文档资料戳这里. 二.具体内容 开发环境 系统环境:Ubuntu 14. ...