python中的多继承以及MRO

MRO

MRO即method resolution order,方法调用顺序。python是一门支持多继承的语言,当一个子类(该子类继承了两个父类)的对象执行方法A时,该子类没有定义方法A,而两个父类都定义了方法A,那么应该执行哪个父类的方法A?这个时候就需要MRO来制定执行顺序。
看个例子

class F():
    pass


class A(F):
    pass


class B(F):
    pass


class C(A, B):
    pass


print(C.mro())

输出结果

[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.F'>, <class 'object'>]

MRO的计算过程
使用O记号来表示某个类的MRO,假如类M的父类为[M1, M2…Mn],
O(M) = [M] + [O(M1), O(M2)…O(Mn), [M1], [M2]…[Mn]]
加号之后是一串列表,其中每个列表的第一个元素为该列表头,列表中的剩余元素为该列表的尾。从一串列表中的最左边开始,取该列表的头,假如该列表的头没有出现在其他列表的尾中,那么就可以把这个头提到列表外,作为次一级优先级的类与之前的合并。同时把该类从所有的列表中删除。一直持续到列表为空。如果最后列表不为空,说明这是个错误的继承,python中会给出异常提示。
还是上边的例子
O(F) = [F]
O(A) = [A] + [O(F)] = [A] + [F] = [A, F]
O(B) = [B] + [O(F)] = [B] + [F] = [B, F]
O[C] = [C] + [O(A), O(B), [A], [B] ]
= [C] + [[A, F], [B, F], [A], [B] ]
= [C, A] + [[F], [B, F], [B] ]
= [C,A,B] + [[F], [F] ]
= [C, A, B, F]
当C的实例调用某个方法时,就按照该顺序进行查找,直到找到实现了该方法的类。

class F():
    def foo(self):
        print('i am f fool')


class A(F):
    pass


class B(F):
    def foo(self):
        print('i am b fool')


class C(A, B):
    pass

C().foo()

输出结果

i am b fool

在沿着MRO查找的过程中,C和A都没有实现该方法,查找到B的时候,发现B实现了该方法,就执行了B的foo方法。

class F():
    def foo(self):
        print('i am f fool')


class A(F):
    def foo(self):
        print('i am a fool')
        super(A, self).foo()


class B(F):
    def foo(self):
        print('i am b fool')


class C(A, B):
    pass

C().foo()

执行结果

i am a fool
i am b fool

在查找foo的方法的过程中,发现A实现了该方法,打印了 i am a fool,由于A的foo方法调用的父类的foo方法,在MRO中可以看到A之后的类为B,于是下一步再执行B类中实现的foo方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值