python mro c3_Python的MRO以及C3線性化算法

 2023-12-06 阅读 28 评论 0

摘要:python3?中的方法解析順序 (Method Resolution Order , MRO)采用C3線性化算法來確定(百度Python MRO排在首位的文章,絕大部分內容是正確的,但是核心公式錯了)簡而言之,一個類的MRO應當如下確定L[object] = [object]L[C(B1…BN)] = [C] + mer

python3?中的方法解析順序 (Method Resolution Order , MRO)采用C3線性化算法來確定

(百度Python MRO排在首位的文章,絕大部分內容是正確的,但是核心公式錯了)

簡而言之,一個類的MRO應當如下確定

L[object] = [object]

L[C(B1…BN)] = [C] + merge(L[B1]…L[BN], [B1, … ,BN])

這里的關鍵在于?merge,其輸入是一組列表,按照如下方式輸出一個列表:

檢查第一個列表的頭元素(如?L[B1]?的頭),記作?H。

若?H?未出現在其它列表的尾部,則將其輸出,并將其從所有列表中刪除,然后回到步驟1;否則,取出下一個列表的頭部記作?H,繼續該步驟。

重復上述步驟,直至列表為空或者不能再找出可以輸出的元素。如果是前一種情況,則算法結束;如果是后一種情況,說明無法構建繼承關系,Python 會拋出異常。

示例1

繼承關系如下圖

根據上述C3算法的步驟來計算其MRO

首先計算B1的MRO:

L[B1(A1,A2)] = [B1] + merge(L[A1], L(A2), [A1, A2])

= [B1] + merge([A1,Obj], [A2,Obj], [A1,A2])

= [B1, A1] + merge([Obj], [A2,Obj], [A2])

= [B1, A1, A2] + merge([Obj], [Obj])

= [B1, A1, A2, Obj]

同理,計算B2的MRO(過程略):

L[B2(A3)] = [B2, A3, Obj]

最終計算并得到C的MRO

L[C(B1,B2)] = [C] + merge(L[B1(A1,A2)], L[B2(A3)], [B1,B2])

= [C] + merge([B1, A1, A2, Obj], [B2, A3, Obj], [B1,B2])

= [C, B1] + merge([A1, A2, Obj], [B2, A3, Obj], [B2])

= [C, B1, A1] + merge([A2, Obj], [B2, A3, Obj], [B2])

= [C, B1, A1, A2] + merge([Obj], [B2, A3, Obj], [B2])

= [C, B1, A1, A2, B2] +merge([Obj], [A3, Obj])

= [C, B1, A1, A2, B2, A3] +merge([Obj], [Obj])

= [C, B1, A1, A2, B2, A3, Obj]

根據C3算法成功構建了MRO,所以這個類的繼承關系是被允許的,而且根據MRO可以明確地指出應當如何去查找其父類的屬性/方法。即按照MRO列表由前向后的順序來查找。

當然,我們完全沒有必要去計算這個序列,直接使用.mro()類方法即可查看該類的MRO

C.mro()

[, , , , , , ]

與我們計算的結果是相同的。

正確理解MRO是使用多重繼承和super()完成多繼承類協作任務的基礎。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/188575.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息