多繼承c3演算法

2022-04-28 15:06:12 字數 1564 閱讀 6585

一.mro

mro即 method resolution order (方法解釋順序),主要用於在多繼承時判斷屬性的路徑(來自於哪個類)。

print(類.mro)得到屬性路徑按繼承順序

在python2.2版本中,演算法基本思想是根據每個祖先類的繼承結構,編譯出一張列表,包括搜尋到的類,按策略刪除重複的。但是,在維護單調性方面失敗過(順序儲存),所以從2.3版本,採用了新演算法c3。

二.為什麼採用c3演算法

c3演算法最早被提出是用於lisp的,應用在python中是為了解決原來基於深度優先搜尋演算法不滿足本地優先順序,和單調性的問題。

本地優先順序:指宣告時父類的順序,比如c(a,b),如果訪問c類物件屬性時,應該根據宣告順序,優先查詢a類,然後再查詢b類。

單調性:如果在c的解析順序中,a排在b的前面,那麼在c的所有子類裡,也必須滿足這個順序。

三.c3演算法

判斷mro要先確定乙個線性序列,然後查詢路徑由由序列中類的順序決定。所以c3演算法就是生成乙個線性序列。

如果繼承至乙個基類:

class b(a)

這時b的mro序列為[b,a]

如果繼承至多個基類

class b(a1,a2,a3 ...)

這時b的mro序列 mro(b) = [b] + merge(mro(a1), mro(a2), mro(a3) ..., [a1,a2,a3])

merge操作就是c3演算法的核心。

遍歷執行merge操作的序列,如果乙個序列的第乙個元素,是其他序列中的第乙個元素,或不在其他序列出現,則從所有執行merge操作序列中刪除這個元素,合併到當前的mro中。

merge操作後的序列,繼續執行merge操作,直到merge操作的序列為空。

如果merge操作的序列無法為空,則說明不合法。

class a(object):pass

class b(object):pass

class c(object):pass

class e(a,b):pass

class f(b,c):pass

class g(e,f):pass

#a、b、c都繼承至乙個基類,所以mro序列依次為[a,o]、[b,o]、[c,o]

#mro(e) = [e] + merge(mro(a), mro(b), [a,b])

#= [e] + merge([a,o], [b,o], [a,b])

#執行merge操作的序列為[a,o]、[b,o]、[a,b]

#a是序列[a,o]中的第乙個元素,在序列[b,o]中不出現,在序列[a,b]中也是第乙個元素,所以從執行merge操作的序列([a,o]、[b,o]、[a,b])中刪除a,合併到當前mro,[e]中。

#mro(e) = [e,a] + merge([o], [b,o], [b])##

mro(e) = [e,a,b] + merge([o], [o])

#= [e,a,b,o]

print(e.__mro__) #

(, , , )

例子

Python多繼承C3演算法

python3 多繼承的mro演算法選擇。mro method resolution order 方法解析順序。python3 只保留了c3演算法!c3演算法解析 1.c3演算法解析 c3演算法 mro是乙個有序列表l,在類被建立時就計算出來了。l child base1,base2 child m...

python多繼承之C3演算法

mro即 method resolution order 方法解釋順序 主要用於在多繼承時判斷屬性的路徑 來自於哪個類 在python2.2版本中,演算法基本思想是根據每個祖先類的繼承結構,編譯出一張列表,包括搜尋到的類,按策略刪除重複的。但是,在維護單調性方面失敗過 順序儲存 所以從2.3版本,採...

python多重繼承C3演算法

python多重繼承的mro演算法選擇 經典方式 python2.2 新式演算法 python2.3 新式演算法 c3 python 3中只保留了最後一種,即c3演算法 c3演算法的解析 1.多繼承uml圖 備註 o object 2.python c3演算法解析 c3 定義引用開始 c3 演算法 ...