python中使用多繼承,會涉及到查詢順序(mro)、重複呼叫(鑽石繼承,也叫菱形繼承問題)等
mromro即method resolution order,用於判斷子類呼叫的屬性來自於哪個父類。在python2.3之前,mro是基於深度優先演算法的,自2.3開始使用c3演算法,定義類時需要繼承object,這樣的類稱為新式類,否則為舊式類
從圖中可以看出,舊式類查詢屬性時是深度優先搜尋,新式類則是廣度優先搜尋
程式設計客棧c3演算法最早被提出是用於lisp的,應用在python中是為了解決原來基於深度優先搜尋演算法不滿足本地優先順序,和單調性的問題。
本地優先順序:指宣告時父類的順序,比如c(a,b),如果訪問c類物件屬性時,應該根據宣告順序,優先查詢a類,然後再查詢b類。
單調性:如果在c的解析順序中,a排在b的前面,那麼在c的所有子類裡,也必須滿足這個順序
示例看下面的例子
# -*- coding:utf-8 -*-
#!python2
class x(object):
def f(self):
print 'x'
class a(x):
def f(self):
print 'a'
def extral(self):
print 'extral a'
class b(x):
def f(self):
print 'b'
def extral(self):
print 'extral b'
class c(a, b, x):
def f(self):
super(c, self).f()
print 'c'
print c.mro()
c = c()
c.f()
c.extral()
根據廣度搜尋原則最先搜尋到a,所以結果很明顯,如下所示
[, , , &程式設計客棧lt;class '__main__.x'>, ]ac
extral b
類c沒有extral函式zwftkvt,呼叫的是子類的該函式。這種類的部分行為由父類來提供的行為,叫做抽象超類.
Python中多繼承與super 用法
python類分為兩種,一種叫經典類,一種叫新式類。兩種都支援多繼承。考慮一種情形,b繼承於a,c繼承於a和b,但c需要呼叫父類的init 函式時,前者會導致父類a的init 函式被呼叫2次,這是不希望看到的。而且子類要顯式地指定父類,不符合dry原則。經典類 class a def init se...
python多繼承及其super的用法
python也具有多繼承的功能,而同樣的,大家能想到多繼承必須要引入一些特定的方法來準確呼叫子類或基類的過載 重寫的方法,否則會出現混亂。本文參考multiple inheritance in python對該問題進行簡要論述。如下圖描述了乙個簡單的類繼承關係 下面是上面類圖的 class1 cla...
python多繼承及其super的用法
python也具有多繼承的功能,而同樣的,大家能想到多繼承必須要引入一些特定的方法來準確呼叫子類或基類的過載 重寫的方法,否則會出現混亂。本文參考multiple inheritance in python對該問題進行簡要論述。如下圖描述了乙個簡單的類繼承關係 下面是上面類圖的 class1 cla...