python多繼承之C3演算法

2022-08-01 18:15:13 字數 1899 閱讀 6751

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

在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操作的序列無法為空,則說明不合法。

例子:實現c3演算法的**

#

-*- encoding:gbk -*-#

def mro_c3(*cls):

if len(cls)==1:

ifnot cls[0].__bases__

:

return

cls

else

:

return cls+ mro_c3(*cls[0].__bases__

)

else

: seqs = [list(mro_c3(c)) for c in cls ] +[list(cls)]

res =

while

true:

non_empty =list(filter(none, seqs))

ifnot

non_empty:

return

tuple(res)

for seq in

non_empty:

candidate =seq[0]

not_head = [s for s in non_empty if candidate in s[1:]]

ifnot_head:

candidate =none

else

:

break

ifnot

candidate:

raise typeerror("

inconsistent hierarchy, no c3 mro is possible

")

for seq in

non_empty:

if seq[0] ==candidate:

del seq[0]

內容摘自:

Python多繼承C3演算法

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

多繼承c3演算法

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

python多重繼承C3演算法

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