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結束被調用") classGrandson(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