Python多重继承超级方法调用

时间:2020-10-30 17:27:28

标签: python multiple-inheritance

我正在阅读this文章,但无法理解以下示例:

class Class1: 
    def m(self): 
      print("In Class1") 
      print("here1")
  
class Class2(Class1): 
    def m(self): 
        print("In Class2") 
        super().m() 
        print("here2")
  
class Class3(Class1): 
    def m(self): 
        print("In Class3") 
        super().m() 
        print("here3")
  
class Class4(Class2, Class3): 
    def m(self): 
        print("In Class4")    
        super().m() 
       
obj = Class4() 
obj.m() 

结果是:

In Class4
In Class2
In Class3
In Class1
here1
here3
here2

为什么按该顺序打印结果?我希望结果是:

In Class4
In Class2
In Class1
here1
here2
In Class3
In Class1
here1
here3

为什么我们输入super().m()Class2被丢弃?它仅在我们完成“ In Class3”的打印时运行。

谢谢

2 个答案:

答案 0 :(得分:1)

那是因为Python的方法解析顺序。 例如,您可以通过调用Class4.mro()来查看类的MRO。 您会看到Class3Class1之前。这是因为Python的MRO(https://www.python.org/download/releases/2.3/mro/)使用C3线性化算法(https://en.wikipedia.org/wiki/C3_linearization)。

引用Guido van Rossum(来自维基百科):

基本上,C3的想法是,如果您在复杂的类层次结构中写下继承关系所强加的所有排序规则,则该算法将确定满足所有类的类的单调排序。如果无法确定这种排序,则算法将失败。

您可以阅读算法,但是我想保留的关于算法的简化视图是: 从本质上讲,它是从左到右的DFS,但是子类将始终早于其超类。

注意:这是规则的简化视图,它既不涉及算法也不涉及失败的情况,但是在大多数情况下,这是记住MRO基础知识的好方法。

答案 1 :(得分:0)

因为您正在调用该超类,所以它首先打印了所有类位置的顺序

def m(self): 
    print("In Class3") 
    super().m() 
    print("here3")

看到您正在调用super()。m(),这将导致父类自身函数运行,该父函数将在该函数中保存print(“ In Classn”)语句,然后将调用下一个super()。m ()导致另一个自我功能被执行。您需要先在此处打印。