4

我一直在尝试理解super()多重继承上下文中的行为。我很困惑为什么super()test2.py 中父类中的调用会导致__init__()父母双方都被调用?

测试1.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'>)

测试2.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'>)
4

1 回答 1

6

您的错误在您的评论中:

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

这不是对object.__init__. 将类 C 和实例都传递给它的原因selfsuper它知道接下来要调用什么,而不仅仅是基于类的超类,而是基于实例的 MRO。本质上,意思是“在自己的 MRO 中super(C, self).__init__调用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 ---因为您在调用超类方法打印每条消息。因此,直到执行一直到 , 才会打印第一条消息B.__init__,然后在返回继承树的途中打印其他消息。)

于 2013-06-24T06:37:25.467 回答