Python高级笔记(四) -- 多继承_方法解析顺序表MRO

1. 多继承以及MRO顺序

1.1 单独调用父类的方法

# -*- encoding=utf-8 -*-

class Parent(object):
    def __init__(self, name):
        print("parent的init开始被调用")
        self.name = name
        print("parent的init结束被调用")


class Son1(Parent):
    def __init__(self, name, age):
        print('Son1的init开始被调用')
        self.age = age
        Parent.__init__(self, name)
        print('Son1的init结束被调用')


class Son2(Parent):
    def __init__(self, name, gender):
        print("Son2的init开始背调用")
        self.gender = gender
        Parent.__init__(self, name)
        print("Son2的init结束被调用")

class Grandson(Son1, Son2):
    def __init__(self, name, age, gender):
        print("Grandson的init开始被调用")
        Son1.__init__(self, name, age)
        Son2.__init__(self, name, gender)
        print("Grandson的init结束被调用")


s = Son1("douzi", 23)
s2 = Son2("douzi2", "")
print("="*20)
s3 = Grandson("douzi3", 24, "")

Son1的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son1的init结束被调用
Son2的init开始背调用
parent的init开始被调用
parent的init结束被调用
Son2的init结束被调用
====================
Grandson的init开始被调用
Son1的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son1的init结束被调用
Son2的init开始背调用-
parent的init开始被调用
parent的init结束被调用
Son2的init结束被调用
Grandson的init结束被调用

上述的操作及其费资源,比如网络编程时候,parent要创建一个socket,多个子类会创建多个socket,费资源。

1.2 C3算法,一套确定每个类只调用一次的算法(className.__mro__输出调用顺序)

所以,要把父类,改成super().__init__() ==> Parent只调用一次

class Parent(object):
    def __init__(self, name, *args, **kwargs):
        print("parent的init开始被调用")
        self.name = name
        print("parent的init结束被调用")


class Son1(Parent):
    def __init__(self, name, age, *args, **kwargs):
        print('Son1的init开始被调用')
        self.age = age
        super().__init__(name, *args, **kwargs)
        print('Son1的init结束被调用')


class Son2(Parent):
    def __init__(self, name, gender, *args, **kwargs):
        print("Son2的init开始背调用")
        self.gender = gender
        super().__init__(self, name, *args, **kwargs)
        print("Son2的init结束被调用")

class Grandson(Son1, Son2):
    def __init__(self, name, age, gender):
        print("Grandson的init开始被调用")
        super().__init__(name, age, gender)
        print("Grandson的init结束被调用")


s = Son1("douzi", 23)
s2 = Son2("douzi2", "")
print("="*20)
s3 = Grandson("douzi3", 24, "")

Son1的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son1的init结束被调用
Son2的init开始背调用
parent的init开始被调用
parent的init结束被调用
Son2的init结束被调用
====================
Grandson的init开始被调用
Son1的init开始被调用
Son2的init开始背调用
parent的init开始被调用
parent的init结束被调用
Son2的init结束被调用
Son1的init结束被调用
Grandson的init结束被调用

MRO属性

super()默认拿着自己的类名到MRO输出中找,找到匹配项的下一个的__init__执行

print(Grandson.__mro__)

(<class '__main__.Grandson'>, <class '__main__.Son1'>, <class '__main__.Son2'>, <class '__main__.Parent'>, <class 'object'>)

1.3 为避免多继承报错,使用不定参数: *args, **kwargs

def test1(a, b, *args, **kwargs):
    print(a)
    print(b)
    print(args)
    print(kwargs)

    test2(a, b, args, kwargs)
    print('-'*10)
    test2(a, b, *args, **kwargs)    # 相当于 test2(11,22,33,44,55, name="douzi", age=18)

def test2(a, b, *args, **kwargs):
    print('----------')
    print(a)
    print(b)
    print(args)
    print(kwargs)


test1(11, 22, 33, 44, 55, name="douzi", age=18)

猜你喜欢

转载自www.cnblogs.com/douzujun/p/10787668.html