python - 为什么在父类 __init__() 中调用 super() 会改变子类 __init__() 的行为?

标签 python multiple-inheritance superclass super method-resolution-order

我一直在努力理解 super() 在多重继承的上下文中的行为。我很困惑为什么在 test2.py 的父类中调用 super() 会导致为父类调用 __init__()

test1.py

#!/usr/bin/env python

class A(object):

    def __init__(self):
        self.A = "A"
        print self.A

class B(object):

    def __init__(self):
        self.B = "B"
        print self.B

class C(A, B):

    def __init__(self):
        self.C = "C"
        print self.C
        super(C, self).__init__()

if __name__ == '__main__':
    print "Without super() in parent __init__():"
    c = C()
    print c.__dict__
    print C.__mro__

产生:

$ ./test.py 
Without super() in parent __init__():
C
A
{'A': 'A', 'C': 'C'}
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>)

test2.py

#!/usr/bin/env python

class A(object):

    def __init__(self):
        self.A = "A"
        print self.A
        super(A, self).__init__()

class B(object):

    def __init__(self):
        self.B = "B"
        print self.B
        super(B, self).__init__()

class C(A, B):

    def __init__(self):
        self.C = "C"
        print self.C
        super(C, self).__init__()

if __name__ == '__main__':
    print "With super() in parent __init__():"
    c = C()
    print c.__dict__
    print C.__mro__

产生:

$ ./test2.py 
With super() in parent __init__():
C
A
B
{'A': 'A', 'C': 'C', 'B': 'B'}
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>)

最佳答案

你的错误在你的评论中:

super(C, self).__init__()  <-- call to object.__init__()

这不是对 object.__init__ 的调用。您将类 C 和实例 self 都传递给 super 的原因是它知道接下来要调用什么,而不仅仅是基于类的父类(super class),而是基于实例的 MRO。本质上,super(C, self).__init__ 的意思是“在自己的 MRO 中调用 C 之后类的 __init__”。

这就是 super 的全部要点 --- 它允许合作继承,其中一个类可以调用 super 来表示“将控制传递给 MRO 中的下一个类” ,而无需在类定义时知道是哪个类。

所以当你调用 super(C, self).__init__ 时,它会调用 A.__init__,因为 A 是 MRO 中 C 之后的下一个类。然后当 A 调用 super(A, self).__init__ 时,调用 B.__init__,因为 B 是 MRO 中 A 之后的类。

(请注意,您的消息以相反的顺序打印 --- B、A、C --- 因为您在调用父类(super class)方法之后打印了每条消息。所以第一条消息没有得到打印直到执行一直到 B.__init__,然后其他消息在返回继承树的路上打印。)

关于python - 为什么在父类 __init__() 中调用 super() 会改变子类 __init__() 的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17269270/

相关文章:

c++ - 多级/多继承期间对象的大小

constructor - 将强制数据传递给 Kotlin 中的父类(super class)

c++ - 将文件或文件名传递给函数

python - python中的归并排序

python - 当我需要返回值时,exec 返回一个非类型

Python BeautifulSoup 循环遍历 div 和多个元素

python:模拟类变量的多重继承

python - 使用 python 数据类实现多重继承

java - 当子类对象存储在父类(super class)数组中时,如何调用子类方法?

java - super() 的正确语法?