MRO类继承先后的异常

代码

class A(object):
    pass

class B(A):
    pass


class C(A, B):
    def __int__(self):
        super(C).__init__()

c_ins = C()
  1. 如果方法在C中不存在,则在A中搜索
  2. 如果方法在A中不存在,则在B 中搜索

报错

TypeError: Cannot create a consistent method resolution
order (MRO) for bases A, B

原因

Python 在查找实例属性/方法时需要决定以什么顺序搜索(直接和间接)基类:它通过线性化继承图来实现这一搜索,即使用称为C3 或 MRO 的算法将基类图转换为序列。这算法会导致四个约束

  1. 每个祖先类只出现一次
  2. 类总是出现在其祖先之前(“单调性”)
  3. 同一类的直接父级应该以与类定义中列出的顺序相同的顺序出现(“一致的本地优先顺序”)
  4. 如果 A 的子类始终出现在B的子类之前,A则应出现在之前B(“一致的扩展优先顺序”)

解决

方案一

基于MRO算法引起的第二个约束,C类继承时,子类BA之前,第三个约束A首先出现。由于无法满足所有约束,因此 python 报告继承层次结构是非法的。(上面定义先继承A,再继承B,实际情况是由于B继承A,所以需要BA前面)

class C(B, A):
    def __int__(self):
        super(C).__init__()

如果某方法是在多个类中定义的,可能需要考虑应该使用哪个类来获取调用的方法。定义基类的顺序会影响此选择。

方案二

直接继承子类B就好,因为B会继承A

class C(B):
    def __int__(self):
        super(C).__init__()

本文作者:朝圣

本文链接:www.zh-noone.cn/2023/10/MRO类继承先后的异常

版权声明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0许可协议。转载请注明出处!

Python多版本安装
0 条评论