• MRO的计算(C3算法及应用)


    在程序中出现了多个类的继承而且出现了菱形继承,并且又要用到super,知道MRO就显得极为重要,我们使用C3算法来计算MRO

    下面通过例子来解释:

    class A:
        pass
    class B(A):
        pass
    class C(A):
        pass
    class D(B,C):
        pass
    class E(C,A):
        pass
    class F(D,E):
        pass
    class N:
        pass
    class O:
        pass
    class M(N,O):
        pass
    class G(E,M):
        pass
    class H(G,F):
        pass

    我们来计算上述代码的MRO

    1.首先把继承树图画出来

    是这样子的(不太好看,凑合一下)

    2.假设C3算法是一个函数式,继承代表相加,然后把函数式写出来,很简单,看着继承树图写,不过顺序要与代码中继承的顺序相同

    L(A) = A

    L(B) = B + L(A)

    L(C) = C + L(A)

    L(D) = D + L(B) + L(C)

    L(E) = E + L(C) + L(A)

    L(F) = F + L(D) + L(E)

    L(M) = M + L(N) + L(O)

    L(G) = G + L(E) + L(M)

    L(H) = H + L(G) + L(F)

    3.函数式写出来了,下来我们进行化简

    L(A) = A

    L(B) = B + L(A) = BA

    L(C) = C + L(A) = CA

    L(D) = D + L(B) + L(C) = D + BA + CA =DBCA

    L(E) = E + L(C) + L(A) = E + CA + A = ECA

    L(F) = F + L(D) + L(E) = F + DBCA + ECA = FDBECA

    L(M) = M + L(N) + L(O) = M + N + O =MNO

    L(G) = G + L(E) + L(M) = G + ECA + MNO = GECAMNO

    L(H) = H + L(G) + L(F) = H + GECAMNO + FDBECA = HGFDBECAMNO

    函数式中的+代表的是merge(),merge规则:

     1. 如果第一个序列的第一个元素,是后续序列的第一个元素,或者不再后续序列中再次出现,则将这个元素合并到最终的方法解析顺序序列中,并从当前操作的全部序列中删除。

      2. 如果不符合,则跳过此元素,查找下一个列表的第一个元素,重复1的判断规则

    最后我们可以来验证

    print(H.__mro__)

    发现顺序与我们算的顺序相同,只不过后边多了个class object,因为我们所有的类都要继承obj,所以也不足为奇

    我们计算MRO就是要为super做铺垫,所以我们来看一道面试题

    class Init(object):
        def __init__(self,v):
            print("init")
            self.val = v
    class Add2(Init):
        def __init__(self,val):
            print("Add2")
            super(Add2,self).__init__(val)
            print(self.val)
            self.val += 2
    class Mult(Init):
        def __init__(self,val):
            print("Mult")
            super(Mult, self).__init__(val)
            self.val *= 5
    class HaHa(Init):
        def __init__(self,val):
            print("HaHa")
            super(HaHa,self).__init__(val)
            self.val /= 5
    class Pro(Add2,Mult,HaHa):
        pass
    class Incr(Pro):
        def __init__(self,val):
            super(Incr,self).__init__(val)
            self.val += 1
    p = Incr(5)
    print(p.val)

    大致看一眼,发现出现了多个继承,还涉及到了super的用法,按照方法一步一步来

    1.画继承树图

    2.然后算出MRO:Incr,Pro,Add,Mult,Haha,Init,(Object)

    3.super是访问MRO中下一个类的内容,秉持着这个原则我们进行稍加分析,这道题只不过是几个super的叠用,答案不难算出来

  • 相关阅读:
    Leetcode86.分隔链表
    Leetcode39.组合总和
    Leetcode31.下一个排列
    剑指Offer35.复杂链表复制
    剑指Offer14-I.剪绳子
    剑指Offer38.字符串的排序
    Leetcode29.两数相除
    232. Implement Queue using Stacks
    程序员跳槽指南
    226. Invert Binary Tree
  • 原文地址:https://www.cnblogs.com/yhrfighting123/p/10615932.html
Copyright © 2020-2023  润新知