轉 -- Python: 多繼承模式下 MRO(Method Resolution Order) 的計算方式關乎super

來源:互聯網
上載者:User

標籤:計算過程   fir   sts   res   ISE   順序   自己   tps   wiki   

大家可能已經知道了,在 Python 3(Python 2 的新式類)中多繼承模式是使用 C3 演算法來確定 MRO(Method Resolution Order) 的。

那麼具體是怎麼計算的呢?本文將基於 https://www.python.org/downlo... 中的幾個例子來講解 MRO 是怎麼計算的。

我們首先來定義一些符號: :

用 CN 表示一個類:C1, C2, C3, ..., CN
C1 C2 C3 ... CN 表示的是一個包含多個類的列表 [C1, C2, C3, ..., CN]
其中: :

head = C1
tail = C2 ... CN
加法運算: :

C + (C1 C2 ... CN) = C C1 C2 ... CN
[C] + [C1, C2, ... ,CN] = [C, C1, C2, ..., CN]
L[C] 表示類 C 的線性值,其實就是 C 的 MRO, 其中 :

L[object] = object
比如有個類 : :

class C(B1, B2, ..., BN): pass
那麼: :

L[C(B1 ... BN)] = C + merge(L[B1] ... L[BN], B1 ... BN)
merge 的計算規則如下:

take the head of the first list, i.e L[B1][0]; if this head is not in the tail of any of the other lists, then add it to the linearization of C and remove it from the lists in the merge, otherwise look at the head of the next list and take it, if it is a good head. Then repeat the operation until all the class are removed or it is impossible to find good heads. In this case, it is impossible to construct the merge, Python 2.3 will refuse to create the class C and will raise an exception.

計算 MRO
先從簡單的類說起: :

class B(object): pass

L[B] = L[B(object)]
= B + merge(L[object])
= B + L[object]
= B object

B.mro()
[<class ‘main.B‘>, <type ‘object‘>]
簡單的子類: :

class C(B): pass

L[C] = L[C(B)]
= C + merge(L[B])
= C + L[B]
= C B object # 從上面已經知道了 L[B] = B object

C.mro()
[<class ‘main.C‘>, <class ‘main.B‘>, <type ‘object‘>]
下面來看一個複雜的例子: :

O = object
class F(O): pass
class E(O): pass
class D(O): pass
class C(D,F): pass
class B(D,E): pass
class A(B,C): pass
很容易就可以想到: :

L[O] = O = object
L[F] = L[F(O)] = F O
L[E] = L[E(O)] = E O
L[D] = L[D(O)] = D O
下面來計算 C, B, A:

L[C]: :

L[C] = L[C(D, F)]
= C + merge(L[D], L[F], DF)
# 從前面可知 L[D] 和 L[F] 的結果
= C + merge(DO, FO, DF)
# 因為 D 是順序第一個並且在幾個包含 D 的 list 中是 head,
# 所以這一次取 D 同時從列表中刪除 D
= C + D + merge(O, FO, F)
# 因為 O 雖然是順序第一個但在其他 list (FO)中不是 head, 跳過,
# 改為檢查第二個list FO # F 是第二個 list 和其他 list 的 head,
# 取 F同時從列表中刪除 F
= C + D + F + merge(O)
= C D F O

C.mro()
[<class ‘main.C‘>, <class ‘main.D‘>, <class ‘main.F‘>, <type ‘object‘>]
L[B]: :

L[B] = L[B(D, E)]
= B + merge(L[D], L[E], DE)
= B + merge(DO, EO, DE)
= B + D + merge(O, EO, E)
= B + D + E + merge(O)
= B D E O

B.mro()
[<class ‘main.B‘>, <class ‘main.D‘>, <class ‘main.E‘>, <type ‘object‘>]
L[A]: :

L[A] = L[A(B, C)]
= A + merge(L(B), L(C), BC)
= A + merge(BDEO, CDFO, BC)
= A + B + merge(DEO, CDFO, C)
# 注意這裡是 C , 因為第一個list 的 head D 不是其他list 的 head
# 所以改為從下一個 list CDFO 開始
= A + B + C + merge(DEO, DFO)
= A + B + C + D + merge(EO, FO)
= A + B + C + D + E + merge(O, FO)
= A + B + C + D + E + F + merge(O)
= A B C D E F O

A.mro()
[<class ‘main.A‘>, <class ‘main.B‘>, <class ‘main.C‘>,
<class ‘main.D‘>, <class ‘main.E‘>, <class ‘main.F‘>, <type ‘object‘>]
到這裡應該已經有一點眉目了。下面再來個上面那些類的變種,可以先自己算算看,後面有詳細的計算過程。

O = object
class F(O): pass
class E(O): pass
class D(O): pass
class C(D,F): pass
class B(E,D): pass
class A(B,C): pass
跟之前唯一的區別是 B(D, E) 變成了 B(E, D) :

L[O] = O = object
L[F(O)] = F O
L[E(O)] = E O
L[D(O)] = D O

L[C] = L[C(D, F)]
= C + merge(L[D], L[F], DF)
= C D F O

L[B] = L[B(E, D)]
= B + merge(L[E], L[D], ED)
= B + merge(EO, DO, ED)
= B + E + merge(O, DO, D)
= B + E + D + merge(O)
= B E D O

B.mro()
[<class ‘main.B‘>, <class ‘main.E‘>, <class ‘main.D‘>, <type ‘object‘>]

L[A] = L[A(B, C)]
= A + merge(L[B], L[C], BC)
= A + merge(BEDO, CDFO, BC)
= A + B + merge(EDO, CDFO, C)
= A + B + E + merge(DO, CDFO, C)
= A + B + E + C + merge(DO, DFO)
= A + B + E + C + D + merge(O, FO)
= A + B + E + C + D + F + merge(O)
= A B E C D F O

A.mro()
[<class ‘main.A‘>, <class ‘main.B‘>, <class ‘main.E‘>,
<class ‘main.C‘>, <class ‘main.D‘>, <class ‘main.F‘>, <type ‘object‘>]
通過這幾個例子應該對如何計算 MRO 已經有所瞭解了,更詳細的資訊可以閱讀 python MRO 文檔 以及 wikipedia 中的 C3 演算法.

轉 -- Python: 多繼承模式下 MRO(Method Resolution Order) 的計算方式關乎super

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.