1. 程式人生 > >python新式類繼承------C3算法

python新式類繼承------C3算法

img 什麽 深度 之前 刪除 根據 找到 類定義 如果

一、引入

mro即method resolution order,主要用於在多繼承時判斷調的屬性的路徑(來自於哪個類)。之前查看了很多資料,說mro是基於深度優先搜索算法的。但不完全正確在Python2.3之前是基於此算法,但從Python2.3起應用了新算法:C3算法。

二、為什麽采用C3算法

C3算法最早被提出是用於Lisp的,應用在Python中是為了解決原來基於深度優先搜索算法不滿足本地優先級,和單調性的問題。 本地優先級:指聲明時父類的順序,比如C(A,B),如果訪問C類對象屬性時,應該根據聲明順序,優先查找A類,然後再查找B類。 單調性:如果在C的解析順序中,A排在B的前面,那麽在C的所有子類裏,也必須滿足這個順序。

三、C3算法的實現

1.多繼承UML圖:

技術分享圖片

2.python-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])

C3算法的本質就是Merge,不斷地把mro()函數返回的序列進行Merge,規則如下:

1. 如果第一個序列的第一個元素,是後續序列的第一個元素,或者不再後續序列中再次出現,則將這個元素合並到最終的方法解析順序序列中,並從當前操作的全部序列中刪除。

2. 如果不符合,則跳過此元素,查找下一個列表的第一個元素,重復1的判斷規則

merge: ① 如果列表空則結束,非空 讀merge中第一個列表的表頭,
② 查看該表頭是否在 merge中所有列表的表尾中。
②-->③ 不在,則 放入 最終的L中,並從merge中的所有列表中刪除,然後 回到①中
②-->④ 在,查看 當前列表是否是merge中的最後一個列表

④-->⑤ 不是 ,跳過當前列表,讀merge中下一個列表的表頭,然後 回到 ②中
④-->⑥ 是,異常。類定義失敗。
表頭: 列表的第一個元素 (列表:ABC,那麽表頭就是A,B和C就是表尾)
表尾: 列表中表頭以外的元素集合(可以為空)
merge 簡單的說即尋找合法表頭(也就是不在表尾中的表頭),如果所有表中都未找到合法表頭則異常。

例如:

L(A(B,C)) = A + merge(L(B),L(C),BC)
= A + merge(BDEO,CEFO,BC)#B是合法表頭
= A + B + merge(DEO,CEFO,C)#D是合法表頭
= A + B + D + merge(EO,CEFO,C)#E不是合法表頭,跳到下一個列表CEFO,此時C是合法表頭
= A + B + D + C + merge(EO,EFO)#由於第三個列表中的C被刪除,為空,所以不存在第三個表,只剩下兩個表;此時E是合法表頭
= A + B + D + C + E + merge(O,FO)#O不是合法表頭,跳到下一個列表FO,F是合法表頭,
= A + B + D + C + E + F + merge(O,O)#O是合法表頭
= A + B + D + C + E + F + O
= [A,B,D,C,E,F,O]

python新式類繼承------C3算法