089 類的封裝

1、什麼是封裝

  • 封裝的自己意思其實就和閉包函數同樣,就是把一個函數和變量全都包在一塊兒,但其實這樣的說法不是很具體,就是一種很片面的解釋

2、爲何要封裝

封裝數據的主要緣由是:保護隱私python

封裝方法的主要緣由是:隔離複雜度(快門就是傻瓜相機爲傻瓜們提供的方法,該方法將內部複雜的照相功能都隱藏起來了,只提供了一個快門鍵,就能夠直接拍照)編程

提示:在編程語言裏,對外提供的接口(接口可理解爲了一個入口),就是函數,稱爲接口函數,這與接口的概念還不同,接口表明一組接口函數的集合體。安全

3、如何封裝

  1. 在類裏面封裝其實就是:閉包

    • 隱藏屬性:經過 __變量名來隱藏
    • 隱藏方法:經過 __方法名來隱藏
  2. 隱藏屬性:是爲了數據的安全編程語言

    • 隱藏nmae屬性的例子
    class Person:
        def __init__(self,name,age):
            self.__name=name
            self.age=age
    p=Person('xichen',18)
    print(p.age)# 這個時候咱們實例化出來的對象是訪問不到類init裏的__name屬性的,
    • 如何訪問被隱藏的屬性函數

      • 經過在列裏面寫一個訪問被隱藏的屬性的接口
      class Person:
          def __init__(self,name,age):
              self.__name=name
              self.age=age
          def get_name(self):
              # print(self.__name)
              return '[----%s-----]'%self.__name
      
      p=Person('xichen',18)
      print(p.age)
      p=Person('xichen',18)
      print(p.get_name())

      [----nick-----]code

      • 經過對象名._類名_被隱藏的屬性名
      print(p._Person__name)

      [----nick-----]對象

3.隱藏方法:爲了隔離複雜度繼承

  • 在繼承中,父類若是不想讓子類覆蓋本身的方法,能夠將方法定義爲私有的接口

  • 方法的隱藏和屬性的隱藏式同樣的
  • 這裏的隱藏的方法不想咱們的隱藏的屬性同樣能夠有方法去用,隱藏的方法是用不了的

class Person:
    def __init__(self,name,age):
        self.__name=name
        self.__age=age
    def __speak(self):
        print('6666')

4、property裝飾器

4.1 property裝飾器有什麼用

它能夠把方法包裝成數據屬性

class Person:
    def __init__(self,name,height,weight):
        self.name=name
        self.height=height
        self.weight=weight
    @property   # 使用語法糖的方式 經過property裝飾器進行裝飾
    def bmi(self):
        return self.weight/(self.height**2)
    
p=Person('xc',1.82,75)
print(p.bmi)    # 使用查看對象屬性的方式  查看方法的返回值
# print(p.bmi())    # 錯誤的使用方法
# p.bmi = 123   # 只能查看,不能進行修改

22.6421929718633

4.2 property之setter和deleter

使用property裝飾器將方法包裝成數據屬性後,是沒法進行修改的

  • 只要經過property裝飾器中的方法 .setter,這樣就能夠修改了
class Person:
    def __init__(self,name,height,weight):
        self.__name=name
        self.__height=height
        self.__weight=weight
    @property
    def name(self):
        return '[個人名字是:%s]'%self.__name

    #用property裝飾的方法名.setter,這樣就能夠修改了
    @name.setter
    def name(self,new_name):
        # if not isinstance(new_name,str):
        if type(new_name) is not str:
            raise Exception('改不了')
        if new_name.startswith('sb'):
            raise Exception('不能以sb開頭')
        self.__name=new_name
        
p=Person('xc',1.82,70)
# 按照屬性進行調用
print(p.name)   # 調用property裝飾器後的方法 name,變爲一個屬性
# 按照屬性進行調用,並修改
p.name='pppp'   # 調用property.setter裝飾器後的方法,能夠進行修改

# 改不了,直接拋異常
# p.name=999
# p.name='sb_xxx'
  • 只要經過property裝飾器中的方法 .deleter,就能夠刪除了

通常沒有這個需求。

class Person:
    def __init__(self, name, height, weight):
        self.__name = name
        self.__height = height
        self.__weight = weight

    @property
    def name(self):
        return '[個人名字是:%s]' % self.__name

    # 用property裝飾的方法名.setter,這樣就能夠修改了
    @name.setter
    def name(self, new_name):
        # if not isinstance(new_name,str):
        if type(new_name) is not str:
            raise Exception('改不了')
        if new_name.startswith('sb'):
            raise Exception('不能以sb開頭')
        self.__name = new_name


p = Person('xc', 1.82, 70)
# 按照屬性進行調用
print(p.name)  # 調用property裝飾器後的方法 name,變爲一個屬性
# 按照屬性進行調用,並修改
p.name = 'pppp'  # 調用property.setter裝飾器後的方法,能夠進行修改
# 改不了,直接拋一異常
# p.name=999
# p.name='sb_xxx'

# 刪除name,會調用property.deleter裝飾的方法
del p.name
相關文章
相關標籤/搜索