python笔记 多继承中

84 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

0 环境

  • 编辑器:pycharm或者vscode
  • 系统版本:windows10
  • python版本:3.9.6

1 MRO前言

在上一篇接近结尾处,提了一下多继承报错MRO的问题,如下图:

image.png

2 MRO探索

MRO --> 方法查询顺序,特性有:本地优先(先自己方法优先,比如自己定义的或者重写,继承表里的查找顺序:从左往右)和单调性(每个子类的查找顺序也要符合要求),一般人都看不下去,就先通过案例观察现象,最终得出观察结果,在去看要满足的特性。

每个类都有个__mro__属性,打印类.__mro__的结果,如下图:

也就说明了,每个类,默认继承object的。 image.png

在A和B类的基础上,在加点料,C多继承A和B(C, A, B, object),D继承B,G继承C,有点数学的味道了, C = C + A + B,现在G = G + C,也就等于G + C + A + B。这里遇到重写的,体现除了本地优先,然后还有单调性的要求,所有子类都要满足顺序查找的条件,下面子类满足了查找条件。

class A:
    def run(self):
        print("A")

class B:
    def run(self):
        print("B")

class C(A, B):
    pass

class C1(B, A):
    pass

class D(B):
    pass

class G(C):
    pass

print(C.__mro__)
print(D.__mro__)
print(G.__mro__)

image.png

现在变一变,H(B,D),(H,B,D,object) --> (H,B,D,B,object)。

class H(B,D):
    pass

最终结果是会报错的。问题出现在B在D的前面,而D呢要求B在它的后面,那么B和D现在产生冲突了(不满足条件),既然不满足查找顺序,也就是说单调性特性不满足了。 image.png

3 总结

多继承也是有一套规则的,不然随着子类越来越多,就会乱了套了,就像排辈分似的。这里需要学习MRO的知识,MRO --> 方法查询顺序(特性:本地优先和单调性),本地优先,比如招生。单调性,保证多继承列表里面所有子类的都满意(一致通过)。然后就会有个疑问,python是怎么做到满足MRO的判断的,下篇见。