【发布时间】:2016-02-25 08:39:00
【问题描述】:
我试图了解多重继承(即C3 algorithm for method resolution order)在 Python 中的工作原理。下面带有经典diamond dependency 的玩具示例给出了与我的直觉相反的结果。
我特别注意到以下几点:
- 按原样运行时(即,
A和AA都有super调用Base,则输出为:<B> <A> <AA> <Base> </Base> </AA> </A> </B>。 - 当仅注释掉标记为
(1)的行(即,在A中没有调用Base构造函数),则输出为<B> <A> </A> </B>。 - 当仅注释掉标记为
(2)的行时(即,在AA中没有调用Base构造函数),则输出为<B> <A> <AA> </AA> </A> </B>。 - 当标记为
(1)和(2)的两行都被注释掉时,输出为<B> <A> </A> </B>。
我的问题是:
- 在情况 1 中,在显式调用
Base构造函数之前,似乎在A的构造函数中执行被中断,跳转到(“递归到”)AA构造函数(好像AA将派生自A),然后下降到Base,然后退出。这是怎么回事? (我理解 MROB->A->AA->Base来自 C3 要求,即在父类之前调用子类。) - 在案例 2 中,为什么
AA的构造函数从未被调用,而在案例 3 中它被调用了? - 在情况 2 和 3 中,尽管在
AA(情况 2)/A(情况 3)的构造函数中进行了显式调用,为什么没有调用Base构造函数? (在示例 1 中,它的调用方式符合我的预期。)
以下是课程的 MRO:
- 类
B:(<class '__main__.B'>, <class '__main__.A'>, <class '__main__.AA'>, <class '__main__.Base'>, <type 'object'>) - 类
A:(<class '__main__.A'>, <class '__main__.Base'>, <type 'object'>) - 类
AA:(<class '__main__.AA'>, <class '__main__.Base'>, <type 'object'>) - 类
Base:(<class '__main__.Base'>, <type 'object'>)
代码:
#!/usr/bin/env python
# Using Python 2.7
class Base(object):
def __init__(self):
print '<Base>',
super(Base, self).__init__()
print '</Base>',
class A(Base):
def __init__(self):
print '<A>',
super(A, self).__init__() # (1)
print '</A>',
class AA(Base):
def __init__(self):
print '<AA>',
super(AA, self).__init__() # (2)
print '</AA>',
class B(A, AA):
def __init__(self):
print '<B>',
super(B, self).__init__()
print '</B>',
if __name__ == '__main__':
obj = B()
【问题讨论】:
-
规范参考:rhettinger's super considered super
标签: python inheritance constructor multiple-inheritance