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

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()完成多继承类协作任务的基础。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值