zoukankan      html  css  js  c++  java
  • day30-mixins机制,派生,鸭子类型

    一、mixins机制

    多继承的正确打开方式:mixins机制
    mixins机制核心:就是在多继承背景下尽可能地提升多继承的可读性
    ps:让多继承满足人的思维习惯=》什么"是"什么

    class Vehicle:
        pass
    
    class FlyMixin:
        def fly(self):
            pass
    
    class CivilAircraft(FlyMixin,Vehicle):  # 民航飞机
        pass
    
    class Helicopter(FlyMixin,Vehicle):  # 直升飞机
        pass
    
    class Car(Vehicle):  # 汽车并不会飞,但按照上述继承关系,汽车也能飞了
        pass
    
    
    import socketserver
    # 补充:通常Mixin结果的类放在左边

    二、在子类派生的新方法中如何重用父类的功能

    方式一:指名道姓调用某一个类下的函数=》不依赖于继承关系

    class OldboyPeople:
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
    
        def f1(self):
            print('%s say hello' %self.name)
    
    
    class Teacher(OldboyPeople):
        def __init__(self,name,age,sex,level,salary):
            OldboyPeople.__init__(self,name,age,sex)
    
            self.level = level
            self.salary=salary
    
    tea_obj=Teacher('egon',18,'male',10,3000)
    print(tea_obj.__dict__)

    方式二:super()调用父类提供给自己的方法=》严格依赖继承关系
    调用super()会得到一个特殊的对象,该对象会参照发起属性查找的那个类的mro,去当前类的父类中找属性

    ps:这里强调下,是发起属性查找的类的mro云查找父类,在mro中假如b在a的后面的话,不管了是不是工的父类,都当做父类来看,去到了里去查找对应方法

    class OldboyPeople:
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
    
        def f1(self):
            print('%s say hello' %self.name)
    
    
    class Teacher(OldboyPeople):
        def __init__(self,name,age,sex,level,salary):
            # super(Teacher,self).__init__(name,age,sex)
            super().__init__(name,age,sex) # 调用的是方法,自动传入对象
    
            self.level = level
            self.salary=salary
    
    # print(Teacher.mro())
    tea_obj=Teacher('egon',18,'male',10,3000)
    print(tea_obj.__dict__)
    super()案例
    class A:
        def test(self):
            print('from A')
            super().test()
    
    class B:
        def test(self):
            print('from B')
    
    class C(A,B):
        pass
    
    
    obj=C()
    obj.test()
    
    print(C.mro())
    比如 在这个案例中obj的c类发起,即从c开始,查找c的mro,即
    cab的顺序,a中有test所以打印  from a,再从发起查找test,
    到b中查找test方法,打印from b

    三、多态

    1、什么多态:同一事物有多种形态

    class Animal:
        pass
    
    class People(Animal):
        pass
    
    class Dog(Animal):
        pass
    
    class Pig(Animal):
        pass

    2、为何要有多态=》多态会带来什么样的特性,多态性
    多态性指的是可以在不考虑对象具体类型的情况下而直接使用对象

    class Animal: # 统一所有子类的方法
        def say(self):
            print('动物基本的发声频率。。。',end=' ')
    
    class People(Animal):
        def say(self):
            super().say()
            print('嘤嘤嘤嘤嘤嘤嘤')
    
    class Dog(Animal):
        def say(self):
            super().say()
            print('汪汪汪')
    
    class Pig(Animal):
        def say(self):
            super().say()
            print('哼哼哼')
    
    
    obj1=People()
    obj2=Dog()
    obj3=Pig()
    
    
    obj1.say()
    obj2.say()
    obj3.say()

    定义统一的接口,接收传入的动物对象
    def animal_say(animal):
    animal.say()

    animal_say(obj1)
    animal_say(obj2)
    animal_say(obj3)

    没有关系也可进行调用


    print('hello'.__len__())
    print([1,2,3].__len__())
    print({'a':1,'b':2}.__len__())

    def my_len(val):
    return val.__len__()

    print(my_len('hello'))
    print(my_len([1,2,3]))
    print(my_len({'a':1,'b':2}))

    len('hello')
    len([1,2,3])
    len({'a':1,'b':2})

    python自带的len方法即这样

    python推崇的是鸭子类型

    class Cpu:
        def read(self):
            print('cpu read')
    
        def write(self):
            print('cpu write')
    
    class Mem:
        def read(self):
            print('mem read')
    
        def write(self):
            print('mem write')
    
    
    class Txt:
        def read(self):
            print('txt read')
    
        def write(self):
            print('txt write')
    
    
    obj1=Cpu()
    obj2=Mem()
    obj3=Txt()
    
    obj1.read()
    obj1.write()
    
    obj2.read()
    obj2.write()
    
    obj3.read()
    obj3.write()

    上面这个是linux系统为例,把所有形式的东西全比做文件,都有读写两种操作,大大的提高了代码的可维护性与拓展性能,

    拿到即可调用读写两种操作功能

    # 了解:
    import abc
    
    class Animal(metaclass=abc.ABCMeta): # 统一所有子类的标准
        @abc.abstractmethod
        def say(self):
            pass
    
    # obj=Animal() # 不能实例化抽象类自己
    
    class People(Animal):
        def say(self):
            pass
    
    class Dog(Animal):
        def say(self):
            pass
    
    class Pig(Animal):
        def say(self):
            pass
    
    #
    # obj1=People()
    # obj2=Dog()
    # obj3=Pig()

    四、绑定方法与非绑定方法

    一:绑定方法:特殊之处在于将调用者本身当做第一个参数自动传入
    1、绑定给对象的方法:调用者是对象,自动传入的是对象
    2、绑定给类的方法:调用者类,自动传入的是类

    import settings
    
    class Mysql:
        def __init__(self,ip,port):
            self.ip=ip
            self.port=port
    
        def func(self):
            print('%s:%s' %(self.ip,self.port))
    
        @classmethod # 将下面的函数装饰成绑定给类的方法
        def from_conf(cls):
            print(cls)
            return cls(settings.IP, settings.PORT)
    
    # obj1=Mysql('1.1.1.1',3306)
    
    obj2=Mysql.from_conf()
    print(obj2.__dict__)
    *************
    settings.py 
    IP='127.0.0.1'
    PORT=3306
    *************

    调用时会自动传入对应对象名或者类名

    二:非绑定方法-》静态方法:
    没有绑定给任何人:调用者可以是类、对象,没有自动传参的效果

    class Mysql:
        def __init__(self,ip,port):
            self.nid=self.create_id()
            self.ip=ip
            self.port=port
    
        @staticmethod # 将下述函数装饰成一个静态方法
        def create_id():
            import uuid
            return uuid.uuid4()
    
        @classmethod
        def f1(cls):
            pass
    
        def f2(self):
            pass
    obj1=Mysql('1.1.1.1',3306)
    print(Mysql.create_id)
    print(Mysql.f1)
    print(obj1.f2)
  • 相关阅读:
    十七、mysql数据库备份
    消费端ACK和重回队列
    RabbitMQ TTL、死信队列
    消费端限流策略
    029异常处理
    028class_part2
    027class_part1
    026json和pickle,xml模块
    025__name__变量和目录结构规范
    024模块的概念
  • 原文地址:https://www.cnblogs.com/xiao-zang/p/12678772.html
Copyright © 2011-2022 走看看