4.10 python 面向对象编程(类、对象、实例、继承、多态、封装、super()、类的装饰器、反射、内置魔术方法) 学习笔记

1 类、对象/实例、实例化

  • 类有一个空间,存储的是定义在class中的所有名字

  • 每一个类又拥有自己的空间,通过对象名.__dict__就可以查看这个对象的属性和值

  • 修改列表/字典中的某个值,或者是对象的某一个属性,都不会影响这个对象/字典/列表所在的内存空间

  • 类实例化所经历的步骤

    1. 类名 () 之后首先会开辟一块内存空间
    2. 调用__init__把空间的内存地址作为self参数传递到函数内部
    3. 所有的这个对象需要使用的属性都需要和self关联起来,进行对象初始化
    4. 执行完init中的逻辑后,self变量会自动的被返回到调用处(发生实例化的地方)
  • 类中定义的变量是静态变量

  • 对象中的变量只属于对象本身,每个对象有属于自己的空间来存储对象的变量

  • 当使用对象名去调用某一属性的时候会有优先在自己的空间中寻找,找不到再去对应的类中寻找

  • 如果自己没有就引用类,如果类也没有就报错

  • 对于类来说,类中的变量所有的对象都是可以读取的,并且读取的是同一份变量

  • 对象可以成为另一个对象的属性,嵌套组合

2 三大特性

1)继承

  • 单继承

    • 调用子类的:子类自己有的时候

    • 调用父类的:子类自己没有的时候

    • 调用子类和父类的的:子类父类都有,在子类中调用父类的 父类名.方法名(self)

      # 子类想要调用父类的方法的同时还想执行自己的同名方法
      # 猫和狗在调用eat的时候既调用自己的也调用父类的,
      # 在子类的方法中调用父类的方法 :父类名.方法名(self)
      class Animal:
          def __init__(self,name,food):
              self.name = name
              self.food = food
              self.blood = 100
              self.waise = 100
          def eat(self):
              print('%s is eating %s'%(self.name,self.food))
          def drink(self):
              print('%s is drinking'%self.name)
          def sleep(self):
              print('%s is sleeping'%self.name)
      
      class Cat(Animal):
          def eat(self):
              self.blood += 100
              Animal.eat(self)
          def climb_tree(self):
              print('%s is climbing'%self.name)
              self.drink()
      
      class Dog(Animal):
          def eat(self):
              self.waise += 100
              Animal.eat(self)
          def house_keep(self):
              print('%s is keeping the house'%self.name)
      小白 = Cat('小白','猫粮')
      小黑 = Dog('小黑','狗粮')
      小白.eat()  # 小白 is eating 猫粮
      小黑.eat()  # 小黑 is eating 狗粮
      print(小白.__dict__)  # {'name': '小白', 'food': '猫粮', 'blood': 200, 'waise': 100}
      print(小黑.__dict__)  # {'name': '小黑', 'food': '狗粮', 'blood': 100, 'waise': 200}
      
  • 多继承

    • 一个类有多个父类,在调用父类方法的时候,按照继承顺序,先继承的就先寻找
  • 所有类默认继承object类,并且继承object类的都是新式类(python3都是)

    • 子类.__base__ 查看子类所有继承的父类
  • 一些方法

    • isinstance() 判断两个对象是否是同一个类(包括父类)
  • 绑定方法和普通函数

    • 判断方式:根据调用方式的不同进行判断,类中是函数,实例化对象中是方法

    • from types import FunctionType,MethodType
      # FunctionType : 函数
      # MethodType : 方法
      class A:
          def func(self):
              print('in func')
      
      print(A.func)  # 函数
      a = A()
      print(a.func)  # 方法
      print(isinstance(a.func,FunctionType))  # False
      print(isinstance(a.func,MethodType))  # True
      print(isinstance(A.func,FunctionType))  # True
      print(isinstance(A.func,MethodType))  # False
      
  • 类属性

    • 类名.__name__ # 类的名字(字符串)
    • 类名.__doc__ # 类的文档字符串
    • 类名.__base__ # 类的第一个父类
    • 类名.__bases__ 类的所有父类构成的元组
    • 类名.__dict__ 类的字典属性
    • 类名.__module__ 类定义所在的模块
    • 类名.__class__ 实例对应的类
  • 进阶:多继承的继承顺序问题(项目和源码)

    • 深度和广度

      • 深度:多个类呈线性继承,长度为深度

        在这里插入图片描述

      • 广度:一个类所继承的所有直接父类数量是广度

        在这里插入图片描述

    • 广度优先(所有新式类):

      • 在走到下一个继承点时,下一个点可以从广度和深度两个方向走的时候,总是先走广度,再走深度。
    • 广度优先遵循的C3算法

      • 如果是单继承 那么总是按照从子类->父类的顺序来计算查找顺序

      • 如果是多继承 需要按照自己本类,父类1,父类2…的这种继承顺序

      • 继承顺序

在这里插入图片描述

  ```python
  # 继承顺序
  # A(0) = [AO]
  # B(A) = [BAO]
  # C(A) = [CAO]
  # D(B) = [DBAO]
  # E(C) = [ECAO]
  # F(D, E)     =   C3(D(B) + E(C))
  #             =   [F] + D(B) + E(C)
  #       F     =   [DBAO] + [ECAO]
  #       FD    =   [BAO] + [ECAO]
  #       FDB   =   [AO] + [ECAO]
  #       FDBE  =   [AO] + {CAO}
  #       FDBEC =   [AO] + [AO]
  #       FDBECA=   [O] + [O]
  #       FDBECAO
  ```

- **merge的规则**

  - 如果一个类出现在从左到右所有顺序的最左侧,并且没有在其他位置出现,那么先提出来作为继承顺序中的一个
  - 一个类出现在从左到右顺序的最左侧,并没有在其他顺序中出现,那么先提出来作为继承顺序中的一个
  - 如果从左到右第一个顺序中的第一个类出现在后面且不是第一个,那么不能提取,顺序向后继续找其他顺序中符合上述条件的类

- **用mro,查看继承顺序  类名.mro()**
  • 进阶:通过继承实现类的开发规范(工作)

    • 抽象类是一个开发规范,约束规范他的所有子类必须实现一些和他同名的方法

    • 实现抽象类的方式

      • 自己手动抛异常方式

        raise 异常名(提示信息) # 主动抛异常

        # class 父类:
        #     def 子类必须实现的方法名(self,参数们):
        #         raise NotImplementedError('提示信息')
        # class 子类(父类):
        #     def 父类要求实现的方法(self,参数们):
        #         print('''code''')
        
      • abc模块调用方式,约束力强

        # from abc import ABCMeta,abstractmethod
        # class 父类(metaclass = ABCMeta):
        #     @abstractmethod
        #     def 子类必须实现的方法名(self,参数们):pass
        # class 子类(父类):
        #     def 父类要求实现的方法(self,参数们):
        #         print('''code''')
        
    • 归一化设计

      # class A:
      #     def 同名功能(self):pass
      # class B:
      #     def 同名功能(self):pass
      #
      # def 函数名(obj):
      #     obj.同名功能()
      

2)封装

  • 封装:把属性或者方法装起来

  • 广义:把属性或者方法装起来,外面不能直接调用,要通过类名调用

  • 狭义:把属性和方法藏起来,外面不能调用

    • 使用私有的三种情况

      • no看no改
      • ok看no改
      • ok看ok改(按照定义的逻辑改)
      # 给一个名字前面加上了双下划綫的时候,这个名字就变成了一个私有的
      # 所有的私有的内容或者名字都不能在类的外部调用,只能在类的内部使用了
      class User:
          def __init__(self,name,passwd):
              self.usr = name
              self.__pwd = passwd  # 私有的实例变量/私有的对象属性
          def get_pwd(self):       # 表示的是用户不能改只能看 私有 + 某个get方法实现的
              return self.__pwd
          def change_pwd(self):    # 表示用户必须调用我们自定义的修改方式来进行变量的修改 私用 + change方法实现
              pass
      
    • 封装的语法

      • 私有的静态变量
      class User:
          __Country = 'China'   # 私有的静态变量
          def func(self):
              print(User.__Country)  # 在类的内部可以调用
      print(User.Country)  # 报错 在类的外部不能调用
      print(User.__Country)# 报错 在类的外部不能调用
      User().func()  # 报错
      
      • 私有的实例变量
      import  hashlib
      class User:
          def __init__(self,name,passwd):
              self.usr = name
              self.__pwd = passwd  # 私有的实例变量
          def __get_md5(self):     # 私有的绑定方法
              md5 = hashlib.md5(self.usr.encode('utf-8'))
              md5.update(self.__pwd.encode('utf-8'))
              return md5.hexdigest()
          def getpwd(self):
              return self.__get_md5()
      alex = User('alex','sbsbsb')
      print(alex.getpwd())  # d6170374823ac53f99e7647bab677b92
      
      • 私有的绑定方法
  • 私有的特点

    • 私有能在类的内部使用

    • 私有不能在类的外部

      • 私有原理:使用私有加下划线后的名字不能从类的外部调用的原因
      class User:
          __Country = 'China'   # 私有的静态变量
          __Role = '法师'   # 私有的静态变量
          def func(self):
              print(self.__Country)  # 在类的内部使用的时候,自动的把当前这句话所在的类的名字拼在私有变量前完成变形
      print(User._User__Country)  # '_User__Country': 'China'
      print(User._User__Role)  # __Role '_User__Role': '法师'
      
      User.__aaa = 'bbb'  # 在类的外部根本不能定义私有的概念
      
    • 私有的内容不能被子类使用

      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()  # 报错
      
  • python中的数据级别

    • public 公有的,类内类外都能用,父类子类都能用
    • private 私有的,本类的类内部能用,其他地方都不能用
    • 不支持protect 保护的,类内能用,父类子类都能用,类外不能用
  • 解释封装的一篇好博客

3)多态

  • python处处是多态,一切皆对象

  • 多态定义

    • 多态:一个类型表现出的多种状态

      # 什么是多态 : 一个类表现出的多种形态,实际上是通过继承来完成的
                  #  如果狗类继承动物类,猫类也继承动物类
                  #  那么我们就说猫的对象也是动物类型的
                  #  狗的对象也是动物类型的
                  # 在这一个例子里,动物这个类型表现出了猫和狗的形态
      
    • 在JAVA情况下,一个参数必须指定类型

      # def eat(动物类型 猫的对象/狗的对象,str 食物):
      #     print('动物类型保证了猫和狗的对象都可以被传递进来')
      
    • python处处是多态,一切皆对象

      • 如果想让两个类型的对象都可以传,那么必须让这两个类继承自同一个父类,在指定类型的时候用父类来指定

        class Payment:pass
        class WeChat(Payment):
            def __init__(self,name):
                self.name = name
            def pay(self,money):
                dic = {'username':self.name,'money':money}
                # 想办法调用微信支付 url连接 把dic传过去
                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}
                # 想办法调用苹果支付 url连接 把dic传过去
                print('%s通过苹果支付%s钱成功' % (self.name, money))
        
  • 鸭子模型

    # 子类继承父类,我们说子类是父类类型的(猫类继承动物,我们说猫也是动物)
    # 在python中,一个类是不是属于某一个类型
    # 不仅仅可以通过继承来完成
    # 还可以是不继承,但是如果这个类满足了某些类型的特征条件
    # 我们就说它长得像这个类型,那么他就是这个类型的鸭子类型
    

4)super方法

  • 使用:super().方法名()

  • 理解:

    • 多继承中:按照mro顺序来寻找当前类的下一个类,不需要传参数,自动就帮我们寻找当前类的mro顺序的下一个类中的同名方法进行调用

      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().func()
              super(D,self).func()
              print('D')
      D().func()  # A, C, B, D
      
    • 单继承中:super就是找父类

      class User:
          def __init__(self,name):
              self.name = name
      class VIPUser(User):
          def __init__(self,name,level,strat_date,end_date):
              # User.__init__(self,name)
              super().__init__(name)              # 推荐的
              # super(VIPUser,self).__init__(name)
              self.level = level
              self.strat_date = strat_date
              self.end_date = end_date
      
      太白 = VIPUser('太白',6,'2019-01-01','2020-01-01')
      print(太白.__dict__)  # {'name': '太白', 'level': 6, 'strat_date': '2019-01-01', 'end_date': '2020-01-01'}
      

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

  • @property

    • 作用:把一个方法伪装成一个属性,在调用这个方法时不需要加 () 就可以直接得到方法返回值

    • 应用

      • 第一个应用场景:简单的property

        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)  # 22
        
      • 第二个应用场景:与私有属性合作

        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
        
      • 应用进阶1 setter

        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
        
        apple = Goods('apple',5)
        print(apple.price)   # 调用的是被@property装饰的price, 4.0
        apple.price = 10     # 调用的是被setter装饰的price
        print(apple.price)  # 8.0
        
      • 应用进阶2 deleter

        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)  # 4.0
        apple.price = 'ashkaksk'
        del apple.price   # 并不能真的删除什么,只是调用对应的被@price.deleter装饰的方法而已
        print(apple.price)  # 报错
        
  • @classmethod

    • 被装饰的方法会成为一个类方法

    • 使用原因:定义了一个方法,默认传self,但这个self没被使用,进行实例化后才可以调用方法

    • 定义:把一个对象绑定的方法修改成一个类方法

    • 作用:

      • 在方法中仍然可以引用类中的静态变量
      • 可以不用实例化对象,就直接用类名在外部调用这个方法
      class Goods:
          __discount = 0.8
          def __init__(self):
              self.__price = 5
              self.price = self.__price * self.__discount
          @classmethod   # 把一个对象绑定的方法 修改成一个 类方法
          def change_discount(cls,new_discount):
              cls.__discount = new_discount
      Goods.change_discount(0.6)   # 类方法可以通过类名调用
      apple = Goods()
      print(apple.price)  # 3.0
      apple.change_discount(0.5)  # 类方法可以通过对象名调用
      apple2 = Goods()
      print(apple2.price)  # 2.5
      
    • 应用:

      • 定义了一个方法,默认传self,但这个self没被使用
      • 并且你在这个方法里用到了当前的类名,或者你准备使用这个类的内存空间中的名字的时候
      import time
      class Date:
          def __init__(self,year,month,day):
              self.year = year
              self.month = month
              self.day = day
          @classmethod
          def today(cls):
              struct_t = time.localtime()
              date = cls(struct_t.tm_year,struct_t.tm_mon,struct_t.tm_mday)
              return date
      
      date对象 = Date.today()
      print(date对象.year)  # 2020
      print(date对象.month)  # 4
      print(date对象.day)  # 10
      
  • @staticmethod

    • 被装饰的方法会成为一个静态方法

      class User:
          pass
          @staticmethod
          def login(a,b):      # 本身是一个普通的函数,被挪到类的内部执行,那么直接给这个函数添加@staticmethod装饰器就可以了
              print('登录的逻辑',a,b)
              # 在函数的内部既不会用到self变量,也不会用到cls类
      
      obj = User()
      User.login(1,2)  # 登录的逻辑 1 2
      obj.login(3,4)  # 登录的逻辑 3 4
      
  • 能定义到类中的内容

    • 静态变量 是个所有的对象共享的变量 有对象\类调用 但是不能重新赋值
    • 绑定方法 是个自带self参数的函数 由对象调用
    • 类方法 是个自带cls参数的函数 由对象\类调用
    • 静态方法 是个啥都不带的普通函数 由对象\类调用
    • property属性 是个伪装成属性的方法 由对象调用 但不加括号
    class A:
        country = '中国'
        def func(self):
            print(self.__dict__)
        @classmethod
        def clas_func(cls):
            print(cls)
        @staticmethod
        def stat_func():
            print('普通函数')
        @property
        def name(self):
            return 'wahaha'
    

6)反射

  • 定义:用字符串数据类型的名字,来操作这个名字对应的函数/实例变量/绑定方法/各种方法

  • 理解:在知道一个变量的字符串数据类型的名字,想要直接调用它,但是调用不到,此时使用反射

  • 格式:

    • 对象名.属性名 ==> getattr(对象名, ‘属性名’)

      class Person:
          def __init__(self,name,age):
              self.name = name
              self.age = age
      alex = Person('alex',83)
      ret = getattr(alex,'name')
      print(ret)  # alex
      
    • hasattr(对象名,属性名) ==> 判断属性是否在对象内能不能反射,防止getattr报错

      class A:
          Role = '治疗'
          def __init__(self):
              self.name = 'alex'
              self.age = 84
          def func(self):
              print('wahaha')
              return 666
      a = A()
      print(hasattr(a,'sex'))  # False
      print(hasattr(a,'age'))  # True
      if hasattr(a,'age'):
          print(getattr(a, 'age'))  # 84
      
    • callable 判断是不是可调用的(方法/函数)

      print(hasattr(a,'func'))  # 报错/True
      if hasattr(a,'func'):
          if callable(getattr(a,'func')):  # 判断是否可调用
              getattr(a,'func')()  # wahaha
      
  • 使用场景:

    • 反射对象的 实例变量

      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')) # 反射对象的实例变量  # alex
      
    • 反射类的 静态变量/绑定方法/其他方法

      print(getattr(a,'func')()) # 反射对象的绑定方法, wahaha 666
      print(getattr(A,'Role')) # 反射对象的静态变量, 治疗
      
    • 模块中的所有变量

      • 被导入的模块

        import a   # 引用模块中的任意的变量
        print(getattr(a,'sww'),a.sww)
        getattr(a,'sww')()
        print(getattr(a,'lst'),a.lst)
        print(getattr(a,'dic'),a.dic)
        print(getattr(a,'we'),a.we)
        
        # 模块a
        class Wechat:pass
        class Alipay:pass
        
        def sww():
            print('爽歪歪')
        lst = [1,2,3,4,5]
        dic = {'k':'v'}
        we = Wechat()
        
      • 当前执行的py文件 ——脚本

        import sys # 反射本模块中的名字
        cat = '小a'
        dog = '小b'
        def pig():
            print('小p')
        print(getattr(sys.modules['__main__'],'cat'))  # 小a
        print(getattr(sys.modules['__main__'],'dog'))  # 小b
        getattr(sys.modules['__main__'],'pig')()  # 小p
        
  • 实例 —— 归一化设计

    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')  # alex通过微信支付400钱成功
    pay('alex',400,'Alipay')  # alex通过支付宝支付400钱成功
    pay('alex',400,'Apple')  # alex通过苹果支付400钱成功
    pay('alex',400,'QQpay')  # alex通过qq支付400钱成功
    

7)一些内置的魔术方法

  • __call__方法 对象 () 调用这个类中的__call__方法

    class A:
        def __call__(self, *args, **kwargs):
            print('-------')
    obj = A()
    print(callable(obj))  # True
    obj()  # -------
    
  • __len__方法 len(对象) 需要实现这个类中的__len__方法

    class Cls:
        def __init__(self,name):
            self.name = name
            self.students = []
        def len(self):
            return len(self.students)
        def __len__(self):
            return len(self.students)
    py22 = Cls('py22')
    py22.students.append('杜相玺')
    py22.students.append('庄博')
    py22.students.append('大壮')
    print(py22.len())  # 3
    print(len(py22))  # 3
    
  • __new__方法

    • 实例化的时候先创建一块对象的空间,有一个指针能指向类 --> __new__方法,再调用init --> __init__

    • 设计模式

      • 单例模式:一个类 从头到尾 只会创建一次self的空间

      • 两种方式:

        • __new__实现

          class Baby:
              __instance = None
              def __new__(cls, *args, **kwargs):  # 构造方法
                  if cls.__instance is None:
                      cls.__instance = super().__new__(cls)
                  return cls.__instance
              def __init__(self,cloth,pants):
                  self.cloth = cloth
                  self.pants = pants
          b1 = Baby('红毛衣','绿皮裤')
          print(b1.cloth)  # 红毛衣
          b2 = Baby('白衬衫','黑豹纹')
          print(b1.cloth)  # 白衬衫
          print(b2.cloth)  # 白衬衫
          
        • python 通过模块导入实现

          # 单例.模块
          class Baby:
              def __init__(self,cloth,pants):
                  self.cloth = cloth
                  self.pants = pants
          
          baby = Baby('红上衣','绿裤子')
          
          from 单例 import Baby
          # 永远只占用单例模块中创建的那个内存空间
          
        • 单例模式详解博客

  • __str__方法 帮助我们在打印/展示对象的时候更直观的显示对象内容,%s str() print()

    • 在打印一个对象的时候 调用__str__方法
    • 在%s拼接一个对象的时候 调用__str__方法
    • 在str一个对象的时候 调用__str__方法
    class clas:
        def __init__(self):
            self.student = []
        def append(self,name):
            self.student.append(name)
        def __repr__(self):
            return str(self.student)
        def __str__(self):
            return 'aaa'
    py22 = clas()
    py22.append('大壮')
    print(py22)  # aaa
    print(str(py22))  # aaa
    print('我们py22班 %s'%py22)  # 我们py22班 aaa
    
  • __repr__方法 是str的备胎方法,同时还和%r有合作关系

    • s如果找不到__str__,就调用__repr__方法
    • 用%r进行字符串拼接 或者用repr(对象)的时候总是调用这个对象的__repr__方法
    class clas:
        def __init__(self):
            self.student = []
        def append(self,name):
            self.student.append(name)
        def __repr__(self):
            return str(self.student)
        # def __str__(self):
        #     return 'aaa'
    py22 = clas()
    py22.append('大壮')
    print(py22)  # ['大壮']
    print(str(py22))  # ['大壮']
    print('我们py22班 %s'%py22)  # 我们py22班 ['大壮']
    

3 补充

1)内置数据结构

  • {} key-value
  • [] 序列
  • () 元组
  • {1, } 集合
  • ‘ ’ 字符串

2)非(python)内置数据结构

  • Queue队列:先进先出 FIFO(FIRST IN FIRST OUT)
    • put 放数据
    • get 取数据
  • Stack栈 :后进先出 LIFO(LAST IN FIRST OUT)
    • put 放数据
    • get 取数据
  • 自定义pickle

3)抽象类实例

# 抽象类 是一个开发的规范 约束它的所有子类必须实现一些和它同名的方法
# 支付程序
    # 微信支付 url连接,告诉你参数什么格式
        # {'username':'用户名','money':200}
    # 支付宝支付 url连接,告诉你参数什么格式
        # {'uname':'用户名','price':200}
    # 苹果支付
# class Payment:     # 抽象类
#     def pay(self,money):
#         '''只要你见到了项目中有这种类,你要知道你的子类中必须实现和pay同名的方法'''
#         raise NotImplementedError('请在子类中重写同名pay方法')
#
# class Alipay(Payment):
#     def __init__(self,name):
#         self.name = name
#     def pay(self,money):
#         dic = {'uname':self.name,'price':money}
#         # 想办法调用支付宝支付 url连接 把dic传过去
#         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}
#         # 想办法调用微信支付 url连接 把dic传过去
#         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}
#         # 想办法调用苹果支付 url连接 把dic传过去
#         print('%s通过苹果支付%s钱成功' % (self.name, money))

# aw = WeChat('alex')
# aw.pay(400)
# aa = Alipay('alex')
# aa.pay(400)
# 归一化设计
# def pay(name,price,kind):
#     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')

# appa = Apple('alex')
# appa.fuqian(500)


# 实现抽象类的另一种方式,约束力强,依赖abc模块
# from abc import ABCMeta,abstractmethod
# class Payment(metaclass=ABCMeta):
#     @abstractmethod
#     def pay(self,money):
#         '''只要你见到了项目中有这种类,你要知道你的子类中必须实现和pay同名的方法'''
#         raise NotImplementedError('请在子类中重写同名pay方法')
#
# class Alipay(Payment):
#     def __init__(self,name):
#         self.name = name
#     def pay(self,money):
#         dic = {'uname':self.name,'price':money}
#         # 想办法调用支付宝支付 url连接 把dic传过去
#         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}
#         # 想办法调用微信支付 url连接 把dic传过去
#         print('%s通过微信支付%s钱成功'%(self.name,money))
#
# WeChat('alex')

注:此文为个人学习笔记(old_boy系列)

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值