類的封裝

  • super
    在py3的用法python

    class A(object):
        def func(self):
            print("A")
    
    
    class B(A):
        def func(self):
            super().func()
            print("B")
    
    
    class C(A):
        def func(self):
            super().func()
            print("C")
    
    
    class D(B, C):
        def func(self):
            super(D, self).func()
            print("D")
    
    
    D().func()
    
    
    class User:
        def __init__(self, name):
            self.name = name
    
    
    class VIPUser(User):
        def __init__(self, name, level, start_date, end_date):
            super().__init__(name)
            self.level = level
            self.start_date = start_date
            self.end_date = end_date
    
    
    太白 = VIPUser('太白', 6, '2019-01-01', '2020-01-01')
    print(太白.__dict__)

    在py2中(新式類/經典類)中的用法安全

    • super是按照mro順序來尋找當前類的下一個類
    • 在py3中不須要傳參數,自動就幫咱們尋找當前類的mro順序的下一個類中的同名方法
    • 在py2中的新式類中,須要咱們主動傳遞參數super(子類的名字,子類的對象).函數名()、
    • 在py2的經典類中,並不支持使用super來找下一個類
    • 在D類中找super的func,那麼能夠這樣寫 super().func()
    • 也能夠這樣寫 super(D,self).func() (而且在py2的新式類中必須這樣寫)
  • 封裝微信

    • 廣義上的封裝 : 把屬性和方法裝起來,外面不能直接調用了,要經過類的名字來調用app

    • 狹義上的封裝 : 把屬性和方法藏起來,外面不能調用,只能在內部偷偷調用函數

      • 使用私有屬性和方法的三種狀況微信支付

        • 沒法看和改code

          class User:
          #     def __init__(self, name, passwd):
          #         self.usr = name
          #         self.__pwd = passwd
          # 
          # alex = User('alex', 'alexsb')
          # 
          # print(alex.__pwd)
          # # AttributeError: 'User' object has no attribute '__pwd'
          # print(alex.pwd)
          # # AttributeError: 'User' object has no attribute '__pwd'
          
          # 給一個名字前面加上了雙下劃綫的時候,這個名字就變成了一個私有的
          # 全部的私有的內容或者名字都不能在累的外部調用,只能在類的內部使用了
        • 可看不可改對象

          class User:
              def __init__(self, name, passwd):
                  self.user = name
                  self.__pwd = passwd
          
              def get_cwd(self):
                  return self.__pwd
          
          alex = User('alex', 'alexsb')
          print(alex.get_cwd())
          # alexsb
          
          # 私有 + 某個get方法實現的
        • 可看可改(須要按照規則來改),ip

          class User:
          #     def __init__(self, name, passwd):
          #         self.user = name
          #         self.__pwd = passwd
          #         
          #     def get_cwd(self):
          #         return self.__pwd
          #     
          #     def set_pwd(self):
          #         pass
          
          # set_pwd表示用戶 必須調用咱們自定義的吸怪方式來進行變量的修改 私有 + changge方法實現
      • 封裝的語法md5

        • 私有的靜態變量

          class User:
              __Country = 'china'
              def func(self):
                  print(User.__Country)
          # print(User.__Country) # 類的外部不能調用
          # AttributeError: type object 'User' has no attribute '__Country'
          User().func()
          # china
        • 私有的實例變量

          import hashlib
          
          
          class User:
              def __init__(self, name, passwd):
                  self.user = name
                  self.__pwd = passwd
          
              def __get_md5(self):
                  md5 = hashlib.md5(self.__pwd.encode("utf-8"))
                  return md5.hexdigest()
          
              def getpwd(self):
                  return self.__get_md5()
          
          
          alex = User('alex', 'alexsb')
          print(alex.getpwd())
        • 私有的綁定方法

          import hashlib
          
          
          class User:
              def __init__(self, name, passwd):
                  self.user = name
                  self.__pwd = passwd
          
              def __get_md5(self):
                  md5 = hashlib.md5(self.__pwd.encode("utf-8"))
                  return md5.hexdigest()
          
              def getpwd(self):
                  return self.__get_md5()
          
          
          alex = User('alex', 'alexsb')
          print(alex.getpwd())
          
          # 全部的私有化都爲了讓用戶不在外部調用類中的某個名字
          # 若是徹底私有化,name這個類的封裝讀更高了
          # 封裝度越高 各類屬性和方法的安全性也越高,可是代碼越複雜
      • 私有的特色

        • 在類的內部使用

          內部能夠正常調用

        • 類的外部使用

          沒法再外部使用

        • 類的子類中使用

          沒法再子類中使用

          # class Foo(object):
          #     def __init__(self):
          #         self.func()
          #
          #     def func(self):
          #         print("in Foo")
          #
          #
          # class Son(Foo):
          #     def func(self):
          #         print("IN SON")
          
          
          # Son()
          # IN SON
          
          
          # class Foo(object):
          #     def __init__(self):
          #         self.__func()
          #
          #     def __func(self):
          #         print("in Foo")
          #
          #
          # class Son(Foo):
          #     def __func(self):
          #         print("in son")
          #
          # Son()
          # in Foo
          
          class Foo(object):
              def __func(self):
                  print("in Foo")
          
          class Son(Foo):
              def __init__(self):
                  self.__func()
          
          Son()
          # AttributeError: 'Son' object has no attribute '_Son__func'
      • 原理

        加了雙下劃線的名字爲啥沒法從類的外部調用

        class User:
            __Country = 'China'
            __Role = '法師'
        
            def func(self):
                print(self.__Country)
        
        # 在類的內部使用的時候,自動的把當前這句話所在的類的名字拼接在私有變量前完成變形
        
        print(User._User__Country)
        print(User._User__Role)
        # China
        # 法師
        
        # __Country -->'_User__Country': 'China'
        # __Role    -->'_User__Role': '法師'
        # User.__aaa = 'bbb'  # 在類的外部根本不能定義私有的概念
      • 類中變量的級別,那些是python支持的,那些是python不支持的

        # public  公有的 類內類外都能用,父類子類都能用         python支持
        # protect 保護的 類內能用,父類子類都能用,類外不能用    python不支持
        # private 私有的 本類的類內部能用,其餘地方都不能用     python支持
  • 類最終的三個裝飾器(內置函數)

    • property

      • 做用 : 把一個方法假裝成一個屬性,在調用這個方法的時候不須要加()就能夠直接獲得返回值

        from math import pi
        
        class Circle:
            def __init__(self, r):
                self.r = r
        
            @property
            def area(self):
                return pi * self.r ** 2
        
        c1 = Circle(5)
        print(c1.r)
        print(c1.area)
        # 5
        # 78.53981633974483

        import time
        
        
        class Person:
            def __init__(self, name, birth):
                self.name = name
                self.birth = birth
        
            @property
            def age(self):
                return time.localtime().tm_year - self.birth
        
        太白 = Person('太白', 1998)
        print(太白.age)

        property的第二個應用場景 : 和私有的屬性合做的

        class User:
            def __init__(self, user, pwd):
                self.user = user
                self.__pwd = pwd
        
            @property
            def pwd(self):
                return self.__pwd
        
        alex = User('alex', 'alexsb')
        print(alex.pwd)
        
        class Goods:
        #     discount = 0.8
        #     def __init__(self, name, origin_price):
        #         self.name = name
        #         self.__price = origin_price
        # 
        #     @property
        #     def price(self):
        #         return self.__price * self.discount
        # 
        # apple = Goods('apple', 5)
        # print(apple.price)
        # # 4.0
      • setter

        class Goods:
        #     discount = 0.8
        #     def __init__(self, name, origin_pricce):
        #         self.name = name
        #         self.__price = origin_pricce
        # 
        #     @property
        #     def price(self):
        #         return self.__price * self.discount
        # 
        #     @price.setter
        #     def price(self, new_value):
        #         if isinstance(new_value, int):
        #             self.__price = new_value
        # 
        # apple = Goods('apple', 5)
        # print(apple.price)
        # apple.price = 10
        # print(apple.price)
        # 4.0
        # 8.0
      • delter

        class Goods:
        #     discount = 0.8
        #     def __init__(self, name, origin_price):
        #         self.name = name
        #         self.__price = origin_price
        # 
        #     @property
        #     def price(self):
        #         return self.__price * self.discount
        # 
        #     @price.setter
        #     def price(self, new_value):
        #         if isinstance(new_value, int):
        #             self.__price = new_value
        # 
        #     @price.deleter
        #     def price(self):
        #         del self.__price
        # 
        # apple = Goods('apple', 5)
        # print(apple.price)
        # apple.price = 'asd'
        # del apple.price # 調用對應的被@price.deleter裝飾的方法
        # print(apple.price)
    • classmethod

    • staticmethod

  • 反射

    用字符串數據類型的名字來操做這個名字對應的函數\實例變量\綁定方法\各類方法

    • .反射對象的 實例變量

      class  Person:
          def __init__(self, name, age):
              self.name = name
              self.age = age
      
          def qqxing(self):
              print("qqxing")
      
      alex = Person('alex', 83)
      wusir = Person('wusir', 74)
      ret = getattr(alex, 'name')
      print(ret)
      ret = getattr(wusir, 'name')
      print(ret)
      ret = getattr(wusir, 'qqxing')
      ret()
      # alex
      # wusir
      # qqxing
    • 反射類的 靜態變量/綁定方法/其餘方法

      class A:
      #     Role = '治療'
      # 
      #     def __init__(self):
      #         self.name = 'alex'
      #         self.age = 84
      # 
      #     def func(self):
      #         print("wahaha")
      #         return 666
      # 
      # a = A()
      # print(getattr(a, 'name'))
      # print(getattr(a, 'func')())
      # print(getattr(A, 'Role'))
      # # alex
      # # wahaha
      # # 666
      # # 治療
    • 模塊中的 全部變量

      • 被導入的模塊

        import a
        print(a.Wechat)
        print(a.Alipay)
        # <class 'a.Wechat'>
        # <class 'a.Alipay'>
        # # 對象名.屬性名 ==> getattr(對象名,'屬性名')
        # # a.Alipay ==> getattr(a,'Alipay')
        print(getattr(a, 'Alipay'))
        print(getattr(a, 'Wechat'))
        # <class 'a.Alipay'>
        # <class 'a.Wechat'>
      • 當前執行的py文件 - 腳本

        import a
        import sys
        # print(sys.modules)
        # print(sys.modules['a'].Alipay)
        # print(a.Alipay)
        # <class 'a.Alipay'>
        # <class 'a.Alipay'>
        
        print(getattr(a, 'Alipay'))
        print(getattr(sys.modules['a'], 'Alipay'))
        # <class 'a.Alipay'>
        # <class 'a.Alipay'>
        
        wahaha = 'hahaha'
        print(getattr(sys.modules['__main__'], 'wahaha'))
        # hahaha
    • 反射實現歸一化思想

      class Payment:pass
      class Alipay(Payment):
          def __init__(self,name):
              self.name = name
          def pay(self,money):
              dic = {'uname':self.name,'price':money}
              print('%s經過支付寶支付%s錢成功'%(self.name,money))
      
      class WeChat(Payment):
          def __init__(self,name):
              self.name = name
          def pay(self,money):
              dic = {'username':self.name,'money':money}
              print('%s經過微信支付%s錢成功'%(self.name,money))
      
      class Apple(Payment):
          def __init__(self,name):
              self.name = name
          def pay(self,money):
              dic = {'name': self.name, 'number': money}
              print('%s經過蘋果支付%s錢成功' % (self.name, money))
      
      class QQpay:
          def __init__(self,name):
              self.name = name
          def pay(self,money):
              print('%s經過qq支付%s錢成功' % (self.name, money))
      import sys
      def pay(name,price,kind):
          class_name = getattr(sys.modules['__main__'],kind)
          obj = class_name(name)
          obj.pay(price)
          # if kind == 'Wechat':
          #     obj = WeChat(name)
          # elif kind == 'Alipay':
          #     obj = Alipay(name)
          # elif kind == 'Apple':
          #     obj = Apple(name)
          # obj.pay(price)
      
      pay('alex',400,'WeChat')
      pay('alex',400,'Alipay')
      pay('alex',400,'Apple')
      pay('alex',400,'QQpay')

    • 反射一個函數

      class A:
          Role = '治療'
          def __init__(self):
              self.name = 'alex'
              self.age = 84
          def func(self):
              print('wahaha')
              return 666
      
      a = A()
      if hasattr(a, 'func'):
          if callable(getattr(a, 'func')):
              getattr(a, 'func')()
      
      # wahaha
相關文章
相關標籤/搜索