成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Python: 多繼承模式下 MRO(Method Resolution Order) 的計算方式

golden_hamster / 1271人閱讀

摘要:大家可能已經(jīng)知道了,在的新式類中多繼承模式是使用算法來確定的。那么具體是怎么計算的呢本文將基于中的幾個例子來講解是怎么計算的。下面再來個上面那些類的變種,可以先自己算算看,后面有詳細的計算過程。

大家可能已經(jīng)知道了,在 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 的計算規(guī)則如下:

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 C(B): pass

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

>>> C.mro()
[, , ]

下面來看一個復(fù)雜的例子: :

>>> 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] 的結(jié)果
     = 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()
[, , , ]

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()
[, , , ]

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()
[, , ,
 , , , ]

到這里應(yīng)該已經(jīng)有一點眉目了。下面再來個上面那些類的變種,可以先自己算算看,后面有詳細的計算過程。

>>> 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

跟之前唯一的區(qū)別是 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()
[, , , ]

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()
[, , ,
 , , , ]

通過這幾個例子應(yīng)該對如何計算 MRO 已經(jīng)有所了解了,更詳細的信息可以閱讀 python MRO 文檔 以及 wikipedia 中的 C3 算法.

參考資料

The Python 2.3 Method Resolution Order | Python.org

C3 linearization - Wikipedia

原文地址: https://mozillazg.com/2016/11...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/44329.html

相關(guān)文章

  • Python繼承

    摘要:中使用多繼承,會涉及到查找順序重復(fù)調(diào)用鉆石繼承,也叫菱形繼承問題等即,用于判斷子類調(diào)用的屬性來自于哪個父類。本地優(yōu)先級指聲明時父類的順序,比如,如果訪問類對象屬性時,應(yīng)該根據(jù)聲明順序,優(yōu)先查找類,然后再查找類。 python中使用多繼承,會涉及到查找順序(MRO)、重復(fù)調(diào)用(鉆石繼承,也叫菱形繼承問題)等 MRO MRO即method resolution order,用于判斷子類調(diào)用...

    crossea 評論0 收藏0
  • Python OOP 面向?qū)ο缶幊?/b>

    摘要:時代,如果需要手動繼承,如多態(tài)多態(tài)是指,不同的子類對象調(diào)用相同的父類方法,會產(chǎn)生多態(tài)多樣結(jié)果的編程特性。 參考:黑馬程序員教程 - Python基礎(chǔ) 面向?qū)ο?OOP三大特性,且三個特性是有順序的: 封裝 繼承 多態(tài) 封裝 指的就是把現(xiàn)實世界的事務(wù),封裝、抽象成編程里的對象,包括各種屬性和方法。這個一般都很簡單,不需要多講。 唯一要注意的就是:推薦從小往大開始封裝、開發(fā)類。比如手槍...

    weknow619 評論0 收藏0
  • 5分鐘了解 Pythonsuper函數(shù)是如何實現(xiàn)繼承

    摘要:和中有一個很大的區(qū)別就是類,無論是類的定義還是類的繼承。中類的繼承可以直接使用關(guān)鍵字代替原來的。中注釋掉了函數(shù),所以并沒有向后繼續(xù)執(zhí)行。如果中仍然有函數(shù)則會繼續(xù)向上去查找中是否有函數(shù)。 showImg(https://img-blog.csdnimg.cn/20190306054027681.png?x-oss-process=image/watermark,type_ZmFuZ3po...

    psychola 評論0 收藏0
  • Python繼承優(yōu)缺點

    摘要:本文重點不要試圖在內(nèi)置類型的子類中重寫方法,可以繼承的可拓展類尋求變通掌握多重繼承中的和了解處理多重繼承的一些建議。子類化的代碼如下輸出小結(jié)上述問題只發(fā)生在語言實現(xiàn)的內(nèi)置類型子類化情況中,而且只影響直接繼承內(nèi)置類型的自定義類。 導語:本文章記錄了本人在學習Python基礎(chǔ)之面向?qū)ο笃闹攸c知識及個人心得,打算入門Python的朋友們可以來一起學習并交流。 本文重點: 1、不要試圖在內(nèi)置...

    Sourcelink 評論0 收藏0
  • Python super()就是這樣

    摘要:所以本文中使用的是新式類,而新式類的搜索算法是算法上面的代碼中是父類,是子類,我們在類重新定義了方法,就是在類的功能基礎(chǔ)基礎(chǔ)上新添功能。在這里的作用就是在子類中調(diào)用父類的方法,這個也是在單繼承常見調(diào)用的用法。 python的類分別有新式類和經(jīng)典類,都支持多繼承。在類的繼承中,如果你想要重寫父類的方法而不是覆蓋的父類方法,這個時候我們可以使用super()方法來實現(xiàn) 注意 Python2...

    laznrbfe 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<