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()完成多繼承類協作任務的基礎。
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态