类的封装

  • 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
相关文章
相关标签/搜索