1. 程式人生 > >Python高級筆記(四) -- 多繼承_方法解析順序表MRO

Python高級筆記(四) -- 多繼承_方法解析順序表MRO

super() pre pla nbsp Coding none 分享圖片 sock main

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)

技術分享圖片

Python高級筆記(四) -- 多繼承_方法解析順序表MRO