我有两个多重继承的例子,看起来是一样的,但我得到了不同的结果顺序。
Joël的第一个例子:
class A(object):
def t(self):
print 'from A'
class B(object):
def t(self):
print 'from B'
class C(A): pass
class D(C, B): pass
因此,我们有:
>>> d = D()
>>> d.t() # Will print "from A"
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.C'>, <class '__main__.A'>,
<class '__main__.B'>, <type 'object'>)
然后在木卫四的第二个例子中:
class First(object):
def __init__(self):
print "first"
class Second(First):
def __init__(self):
print "second"
class Third(First):
def __init__(self):
print "third"
class Fourth(Second, Third):
def __init__(self):
super(Fourth, self).__init__()
print "that's it"
因此,我们有:
>>> f = Fourth()
second
that's it
>>> Fourth.__mro__
(<class '__main__.Fourth'>, <class '__main__.Second'>, <class '__main__.Third'>
<class '__main__.First'>, <type 'object'>)
正如你所看到的,MRO
的流动顺序是不同的,在第二个例子中,它在Third
之前没有到达First
,但在第一个例子中它在到达B
之前经过A
。
没有不一致的地方。MRO基于C3算法,Chaturvedi对此进行了解释,Simionato对此进行了更正式的解释。
关于:
在第二个例子中,它在第三个之前没有达到第一个,但在第一个例子,它在去B之前经过A。
由于Third
是由定义的
class Third(First):
Third
必须显示在MRO中的First
之前。
查图维迪用规则解释了这一点
如果A是B的超类,那么B优先于A。或者,B应该在所有
__mro__
(同时包含两者(中,始终出现在A之前。
而在第一示例中,First
和Third
的等价物是A
和C
。由于C
是由定义的
class C(A):
在MRO中,CCD_ 15位于CCD_ 16之前。
为什么A
先于B
更为复杂。这最终是由于在D
的基础上,C
被列在B
之前。在Simionato的记法中,
L[D] = L[D(C,B)] = D + merge(L[C], L[B], CB)
= D + merge(CAO, BO, CB)
= D + C + merge(AO, BO, B)
= D + C + A + merge(O, BO, B)
= D + C + A + B + merge(O, O)
= D + C + A + B + O
在第二个例子中,
L[4] = L[4(2, 3)] = 4 + merge(L[2], L[3], 23)
= 4 + merge(21O, 31O, 23)
= 4 + 2 + merge(1O, 31O, 3)
= 4 + 2 + 3 + merge(1O, 1O) # Third must come before First
= 4 + 2 + 3 + 1 + merge(O, O)
= 4 + 2 + 3 + 1 + O
操作规则为:
取第一个列表的头,即L[B1][0]如果此头不在任何其他列表的尾部,则将其添加到线性化的,并将其从合并中的列表中删除,否则请查看排在下一个名单的首位,如果是好的话,就拿下它。然后重复操作,直到所有类都被删除,或者不可能找到好的头脑。在这种情况下,不可能构建merge,Python 2.3将拒绝创建类C,并将引发例外
(我的重点解释了为什么Third
必须在First
之前(。
这不一样,在第一个例子中,所有"dad"对象都继承对象,因为D加载C,C加载A,按照MRO的顺序,B(由D调用(
在第二个例子中,所有"dad"对象都继承了类First。此时,Python最后加载First,因为它需要处理Second和Third。
附言:这是我的理论,但这只是逻辑。
以下是您在他的示例中实现的一个运行示例:http://ideone.com/pfzXiG
class First(object):
def __init__(self):
print "first"
class Second(First):
def __init__(self):
print "second"
class Third(First):
def __init__(self):
print "third"
class Fourth(Second, Third):
def __init__(self):
super(Fourth, self).__init__()
print "that's it"
print "First: "
print Fourth.__mro__
class First(object):
def __init__(self):
print "first"
class Second(object):
def __init__(self):
print "second"
class Third(First):
def __init__(self):
print "third"
class Fourth(Third, Second):
def __init__(self):
super(Fourth, self).__init__()
print "that's it"
print "Second:"
print Fourth.__mro__
您的第一个继承继承体系如下所示:
D
|
C B
| |
A |
|
object
而你的第二个是:
4
|
2 3
|
1
|
object
为什么在第二示例中它没有在
Third
之前到达First
,而在第一示例中它在到达B
之前经过A
?
你为什么期望这些人也有同样的行为?从图中可以看出,A
和B
之间的关系与First
和Third
之间的关系完全不同。