Python 子类继承了多个父类 , MRO查找调用方法

 

 

在 Python 中,如果一个子类继承了多个父类,而这些父类中都有同名的方法或属性,那么子类在调用这个方法或属性时,会按照 MRO(Method Resolution Order,方法解析顺序)的规则进行查找和调用。在 Python 中,MRO 的顺序是由 C3 算法计算出来的。C3 算法是一种基于拓扑排序和合并的算法,用于计算出多继承的类的方法解析顺序。

如果一个子类没有定义与父类同名的方法或属性,那么当调用这个方法或属性时,就会按照 MRO 的顺序访问父类的方法或属性。MRO 的顺序是由子类的 mro 属性决定的,该属性是一个元组,其中包含了所有父类和子类的类对象。

如果想要控制子类先访问哪个父类的方法,可以通过修改子类的 mro 属性来实现。例如,如果想要让子类先访问父类 A 的方法,可以这样写:

 

 

class A:
    def method_a(self):
        print("A's method_a")

class B:
    def method_a(self):
        print("B's method_a")

class C(A, B):
    pass

class D(B, A, C):
    __mro__ = (D, B, A, C)

d = D()
d.method_a()  # 输出:B's method_a

 

在上面的例子中,子类 D 继承了父类 A 和 B,而这两个父类都定义了 method_a 方法。为了让子类先访问父类 B 的方法,可以将子类的 mro 属性修改为 (D, B, A, C)。这样,当子类调用 method_a 方法时,就会先访问父类 B 的方法。

需要注意的是,修改 mro 属性可能会导致继承链的混乱和代码的可读性变差,因此应该谨慎使用。

 

 


 

 

 

 

在 Python 中,无法直接只针对某个方法来修改 __mro__ 属性,因为 __mro__ 属性是类级别的,它影响到整个类的方法解析顺序。同时,一个类的多个方法可能会共享相同的 MRO,因此修改其中一个方法的 MRO 可能会影响到其他方法的继承顺序。

如果你需要针对某个方法的继承顺序进行修改,可以考虑将该方法移到一个单独的基类中,并让该基类继承自原来的父类。这样就可以通过修改基类的 __mro__ 属性来实现针对该方法的继承顺序修改,而不会影响到其他方法的继承顺序。例如:

 

class MyBaseClass(object):
    # 定义针对 method_a 的 MRO
    __mro__ = (object,)

class MyClass(MyBaseClass, OtherBaseClass):
    def method_a(self):
        pass

    def method_b(self):
        pass

 

在上面的示例中,我们将 method_a 移到了 MyBaseClass 中,并将 MyBaseClass 继承自 object 类。这样就可以通过修改 MyBaseClass.__mro__ 来实现针对 method_a 的继承顺序修改,而不会影响到 method_b 和其他方法的继承顺序。

 

posted @ 2023-06-05 20:02  AngDH  阅读(50)  评论(0编辑  收藏  举报