今天談談多重繼承的優缺點。
super().show_breed()呼叫父類別的方法,結果每一個類別的方法只會呼叫一次:
Timba接著Hardwood很易理解。但Hardwood的上一層是Tree,為甚麼不會先執行,而是讓給Confider,Tree在最後才呼叫呢?Method Resolution Order(MRO)的原則,依照一定的順序搜尋各層別的同名方法,搜尋到就執行,然後終止搜尋。舊版Python搜尋採用DLR or depth-first left to right algorithm(深度優先搜尋演算法或前序遍歷算法),而目前Python的MRO己換用改良後的C3 Linearization Algorithm。Zen1)到六祖惠能(Zen6),分別代表六個類別,來觀察Python的MRO如何運作:
class Zen1(): # 初祖
def show_class_name(self):
print(__class__.__name__) # 本class名。
print(super().__class__.__name__) # 呼叫父類別(class 'object')名。
class Zen2(Zen1): # 二祖
def show_class_name(self) :
print(__class__.__name__)
super().show_class_name() # 呼叫父類別的show_class_name()。
class Zen3(Zen2, Zen1): # 三祖
def show_class_name(self) :
print(__class__.__name__)
super().show_class_name()
class Zen4(Zen3, Zen2, Zen1): # 四祖
def show_class_name(self) :
print(__class__.__name__)
super().show_class_name()
class Zen5(Zen2, Zen1): # 五祖
def show_class_name(self) :
print(__class__.__name__)
super().show_class_name()
class Zen6(Zen4, Zen5, Zen3): # 六祖
def show_class_name(self) :
print(__class__.__name__)
super().show_class_name()
zen = Zen6() # 搜尋程序將從六祖開始。
zen.show_class_name()
print()
print(Zen6.mro()) # Method Resolution Order
C3 Linearization Algorithm的搜尋過程大致如下(註1):
Zen6)開始搜尋。;Zen4)。注意:四祖並未被其他類別所繼承,所以是「好」的節點(好的節點才要搜尋);Zen5)。五祖沒有被其他各祖繼承,是好節點,搜之;Zen3)。Zen2)和初祖(Zen1)。Zen6➞Zen4➞Zen5➞Zen3➞Zen2➞Zen1。Zen1呼叫其super(),由於Zen1並無外顯繼承,Python會自動將class object繼承給它。亦即Python萬物皆源出於class object,好比所有人類均來自非洲草原。不過Zen1的print(super().__class__.__name__)印出的是super而不是object就是。got a poor reputation,名聲不好。註1: