MRO(Method Resolution Order)是指多继承中确定方法调用顺序的算法。Python 3 默认使用 C3 算法来计算 MRO。
在使用多继承时,以下是一些 MRO 的最佳实践、坑和示例:
最佳实践:
- 明确继承关系:在设计类的继承结构时,要清晰明确地指定父类和子类之间的继承关系,避免混乱或歧义。
- 使用super():在重写父类方法时,可以使用
super()函数来调用父类的方法。这样可以确保方法按照正确的 MRO 被调用,并且能够避免冲突和循环调用。 - 理解MRO算法:了解 C3 算法以及 MRO 的计算规则,可以帮助理解多继承的调用顺序,避免意外行为。
常见坑:
- 方法冲突:当不同的父类中存在相同名称的方法时,如果没有明确指定调用哪个父类的方法,可能会导致意外的结果。可以使用重命名、调整继承顺序或使用
super()来解决这个问题。 - 菱形继承问题:当一个子类同时继承自两个或更多个具有共同父类的类时,可能会出现菱形继承问题。这时需要确保继承结构合理并使用正确的 MRO 算法。
1 ''' 2 MRO(Method Resolution Order)是指多继承中确定方法调用顺序的算法。Python 3 默认使用 C3 算法来计算 MRO。 3 4 在使用多继承时,以下是一些 MRO 的最佳实践、坑和示例: 5 6 最佳实践: 7 1. 明确继承关系:在设计类的继承结构时,要清晰明确地指定父类和子类之间的继承关系,避免混乱或歧义。 8 2. 使用super():在重写父类方法时,可以使用 super() 函数来调用父类的方法。这样可以确保方法按照正确的 MRO 被调用,并且能够避免冲突和循环调用。 9 3. 理解MRO算法:了解 C3 算法以及 MRO 的计算规则,可以帮助理解多继承的调用顺序,避免意外行为。 10 11 常见坑: 12 1. 方法冲突:当不同的父类中存在相同名称的方法时,如果没有明确指定调用哪个父类的方法,可能会导致意外的结果。可以使用重命名、调整继承顺序或使用 super() 来解决这个问题。 13 2. 菱形继承问题:当一个子类同时继承自两个或更多个具有共同父类的类时,可能会出现菱形继承问题。这时需要确保继承结构合理并使用正确的 MRO 算法。 14 ''' 15 16 17 class A: 18 def say_hello(self): 19 print("Hello from A") 20 21 22 class B(A): 23 def say_hello(self): 24 print("Hello from B") 25 super().say_hello() 26 27 28 class C(A): 29 def say_hello(self): 30 print("Hello from C") 31 super().say_hello() 32 33 34 class D(B, C): 35 def say_hello(self): 36 print("Hello from D") 37 super().say_hello() 38 39 40 d = D() 41 d.say_hello() 42 43 # 输出结果: 44 # Hello from D 45 # Hello from B 46 # Hello from C 47 # Hello from A
在上述示例中,类 D 继承自类 B 和 C,它们又都继承自类 A。当调用 d.say_hello() 时,按照 MRO 的顺序,先调用 D 的 say_hello() 方法,然后调用 B 的 say_hello() 方法,并调用 C 的 say_hello() 方法,最后调用 A 的 say_hello() 方法。
通过使用 super() 函数,可以确保方法按照正确的 MRO 被调用,实现了多继承的协作和顺序调用。
总之,在使用多继承时,理解 MRO 算法、明确继承关系和使用 super() 函数是避免问题、提高代码可读性和维护性的关键。
如果把D类的方法删除即
1 class D(B, C): 2 pass 3 # def say_hello(self): 4 # print("Hello from D") 5 # super().say_hello()
输出:
Hello from B
Hello from C
Hello from A