python基础 day26 面向对象—super、内置函数property setter 反射

一、内容回顾

1、类的种类

  • 新式类:继承object的类就是新式类,在py3中所有的类都是新式类,在py2中主动继承object的是新式类

  • 经典类:只有py2中,不继承object的就是经典类

1、继承顺序

  • 深度优先 经典类

  • 广度优先 新式类

    • 查看广度优先的顺序:类名.mro()

    • 遵循C3算法

2、抽象类

  • 为了约束规范子类必须实现父类的同名方法

3、归一化设计

4、多态

  • 一个类表现出的多种形态,主要指的是一个子类的对象也是父类类型

二、今日内容

1、super

  • super是按照mro顺序来寻找当前类的下一个类

  • 在python3中不需要传递参数

  • 在python2中的新式类,需要主动传递参数(子类的名字,子类的对象) # super(D,self).func()

  • 在单继承的程序中,super就是找父类

  • class User:
       def __init__(self,age):
           self.age = age
    class VipUser(User):
       def __init__(self,name,age,level,star_date):
           super().__init__(age)
           self.name = name
           self.level = level
           self.star_date = star_date
    v = VipUser('太白',22,12,'2020-01-01')
    print(v.__dict__)


    class A:
       def func(self):
           print('in a')
    class B(A):
       def func(self):
           super().func()
           print('in b')

    class C(A):
       def func(self):
           super().func()
           print('in c')
    class D(B,C):
       def func(self):
           super().func()
           #super(D,self).func() #python 2中这样传递参数
           print('in d')
    D().func()

    # D().func()
    # D,B,C,A
    # super是按照mro顺序来寻找当前类的下一个类
    # 在py3中不需要传参数,自动就帮我们寻找当前类的mro顺序的下一个类中的同名方法
    # 在py2中的新式类中,需要我们主动传递参数super(子类的名字,子类的对象).函数名()
    # 这样才能够帮我们调用到这个子类的mro顺序的下一个类中的方法
    # 在py2的经典类中,并不支持使用super来找下一个类

     

2、封装

  • 定义: 就是把属性和方法装起来

  • 广义上的封装

    • 把属性和方法装起来,外面不能调用,要通过类的名字调用

  • 狭义上的封装 :把属性和方法藏起来,外面不能调用,只能在内部调用

    • 封装的语法 :给一个名字前面添加双下划线,会变成一个私有的

      • 所有的私有的内容或名字,都不能在类的外部调用,只能在类的内部使用

      • 私有的静态变量

        #############私有静态变量###############
        class Apple:
           __County = '中国'  #名称已改变 _Apple__County
           def __init__(self,name,price):
               self.name = name
        a = Apple('alex',20)
        print(Apple.__dict__)  # '_Apple__County': '中国'
        print(a.__dict__)  #{'name': 'alex'}
        # print(Apple.__County)
        # print(a.__County)

         

      • 私有的实例变量

        class Resister:
           def __init__(self,name,pwd):
               self.name = name
               self.__pwd = pwd  #名称已改变   _Resister__pwd
           def get_pwd(self):
               return self.__pwd
        alex = Resister('alex',123)
        print(alex.get_pwd())
        print(alex.__dict__)  #{'name': 'alex', '_Resister__pwd': 123}
        # print(alex.__pwd) #无法查看

         

      • 私有的绑定方法

        ##################私有的绑定方法######################
        class Foo:
           def __init__(self,name):
               self.name = name
           def __func(self):  #'_Foo__func': <function Foo.__func at 0x000001DA26603E18>
               print(self.name)
        # print(Foo('alex').__func())
        print(Foo.__dict__)

         

      • 私有的内容不能被继承,在私有化时,私有的名称已经发生变化,只有在本类中,才会替换成自己通过self调用的

        class Resister:
           def __init__(self,name,pwd):
               self.name = name
               self.__pwd = pwd  #名称已改变   _Resister__pwd
           def get_pwd(self):
               return self.__pwd
        alex = Resister('alex',123)
        print(alex.get_pwd())
        print(alex.__dict__)  #{'name': 'alex', '_Resister__pwd': 123}
        # print(alex.__pwd) #无法查看



        class Foo:
           def __init__(self):
               self.func()
           def func(self):
               print('in Foo')
        class Role(Foo):
           def func(self):
               print(' in role')
        Role()   #' in role'


        class Foo:
           def __init__(self):
               self.__func()
           def __func(self):
               print('in Foo')
        class Role(Foo):
           def __func(self):
               print(' in role')
        Role()   #' in Foo'
        print(Foo.__dict__)  # _Foo__func
        print(Role.__dict__)  # _Role__func

         

    • 封装的原理

3、类中的三个装饰器(内置函数)

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

    # class Apple:
    #     def __init__(self,name,price):
    #         self.name = name
    #         self.__price =price
    #     def price(self):
    #         return self.__price
    # a = Apple('apple',220)
    # print(a.name)
    # print(a.price())
    ###############把一个方法伪装成属性######################
    class Apple:
       def __init__(self,name,price):
           self.name = name
           self.__price =price
       @property
       def price(self):
           return self.__price
    a = Apple('apple',220)
    print(a.name)
    print(a.price)  #————》print(a.price())


    ###################更改私有实例变量的值########################
    #
    class Apple:
       def __init__(self,name,price):
           self.name = name
           self.__price =price
       @property
       def price(self):
           return self.__price
       @price.setter  #更改私有实例变量的值
       def price(self,new_price):
           self.__price = new_price
    a = Apple('apple',220)
    print(a.name)
    print(a.price)  # 220 ————》print(a.price())
    a.price = 100  #@price.setter 执行这个装饰器内的内容
    print(a.price)  #100

    #####################删除私有实例变量##########################
    class Apple:
       def __init__(self,name,price):
           self.name = name
           self.__price =price
       @property
       def price(self):
           return self.__price
       @price.setter  #更改私有实例变量的值
       def price(self,new_price):
           self.__price = new_price
       @price.deleter  # 删除私有实例变量
       def price(self):
           del self.__price
    a = Apple('apple',220)
    print(a.name)
    print(a.price)  # 220 ————》print(a.price())
    a.price = 100  #@price.setter 执行这个装饰器内的内容
    print(a.price)  #100
    del a.price
    # print(a.price)

     

  • classmethod

  • staticmechod

4、反射

  • hasattr :判断字符串是否在反射的对象中 存在True 不存在 False

  • getattr

  • 几种情况

    • 反射模块中的内容

    • 反射本文件中的内容

    • 反射对象的属性和绑定方法

    • 反射类的静态变量

  • callable判断是否可被调用

  • 实际例子-归一化设计

    import sys
    class Payment:  ##这个类就是一个约束类,并且是一个抽象类
       def pay(self,money):
           raise NotImplementedError("必须实现一个同名函数pay")
    class ApplePay:
       def __init__(self,name):
           self.name = name
       def pay(self,money):
           print(f'你通过{self.name}支付了{money}钱!')
    class Wechat:
       def __init__(self,name):
           self.name = name
       def pay(self,money):
           print(f'你通过{self.name}支付了{money}钱!')
    class Alipay:
       def __init__(self,name):
           self.name = name
       def pay(self,money):
           print(f'你通过{self.name}支付了{money}钱!')
    #归一化设计
    def pay(name,money,kind):
       if hasattr(sys.modules['__main__'],kind): #判断对象是否在类中
           if callable(getattr(sys.modules['__main__'],kind)): #判断实例化的对象是否可被调用
               obj = getattr(sys.modules['__main__'],kind)(name) # ==obj.kind(name)
               obj.pay(money)
    pay('alex',200,'Wechat')
    pay('wusir',200,'ApplePay')

    #反射模块中的内容
    print(getattr(sys.modules['__main__'],'Wechat'),Wechat) #<class '__main__.Wechat'> <class '__main__.Wechat'>
    print(getattr(sys.modules['__main__'],'Wechat')('alex'))  #== Wechat('alex')
    #反射对象的属性和绑定方法
    print(getattr(sys.modules['__main__'],'Wechat')('alex').name)  # Wechat('alex').name
    print(getattr(ApplePay,'pay')) # print(ApplePay.pay)
    getattr(ApplePay('alex'),'pay')(200)  #反射类中的绑定方法
    ApplePay('alex').pay(2000)
    import a
    print(a.name)
    print(getattr(a,'name'))#反射模块中的内容
    print(getattr(a,'age'))  #反射模块中的内容
    from a  import A
    obj = A('alex')
    print(obj.name)
    print(getattr(A('wusir'),'name'))  #反射模块中的实例变量
    res = getattr(A("alex"),'func') #反射a模块中的class A
    res()  # in a 模块 in A 类
  •  

原文地址:https://www.cnblogs.com/iaoyuyuyuhuanghuang/p/14268648.html