在Python中创建两次Object

Bry*_*yan 11 python oop inheritance

我读过Expert Python Programming,它有一个多继承的例子.书的作者已经解释过,但我不理解,所以我想有另一种观点.

该示例显示对象B已创建两次!

你能给我一个直观的解释吗?

In [1]: class A(object):
    ...:     def __init__(self):
    ...:         print "A"
    ...:         super(A, self).__init__()

In [2]: class B(object):
    ...:     def __init__(self):
    ...:         print "B"
    ...:         super(B, self).__init__()

In [3]: class C(A,B):
    ...:     def __init__(self):
    ...:         print "C"
    ...:         A.__init__(self)
    ...:         B.__init__(self)

In [4]: print "MRO:", [x.__name__ for x in C.__mro__]
MRO: ['C', 'A', 'B', 'object']

In [5]: C()
C
A
B
B
Out[5]: <__main__.C at 0x3efceb8>
Run Code Online (Sandbox Code Playgroud)

书的作者说:

这是由于A.__init__(self)使用C实例进行的super(A, self).__init__()调用而发生B的,因此调用了构造函数

我没有理解的一点是A.__init__(self)调用将如何调用super(A, self).__init__()call B的构造函数

Mik*_*ler 8

super()意味着"下一行",其中行是mro ['C', 'A', 'B', 'object'].所以接下来A就是B.

mro根据称为C3线性化的算法计算.当你使用时super(),Python只是遵循这个顺序.当你编写课程时,A你还不知道下一课是哪一课.只有在您创建C具有多重继承的类并运行程序后,您才能获得mro并"知道"下一步将会是什么A.

对于您的示例,它意味着:

C()调用__init__()C,其中调用__init__()A.现在,A使用super()和发现B的MRO,因此它调用__init__()B.接下来,__init__()C调用__init__()B一次.

调用super()__init__()创建一个不同的MRO,并避免了对双通话__init__()B.

from __future__ import print_function

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

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

class C(A,B):
    def __init__(self):
        print("C")
        super(C, self).__init__()
Run Code Online (Sandbox Code Playgroud)

使用:

>>> C.mro()
[__main__.C, __main__.A, __main__.B, object]
>> C()
C
A
B
Run Code Online (Sandbox Code Playgroud)