我有两个多重继承的例子看起来是一样的,但我得到了不同的结果顺序。
来自First Example的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'>)
然后来自Second Example的Callisto:
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
的流顺序不同,在第二个示例中,它在First
之前未到达Third
,但在第一个示例中它通过了A
1}}在转到B
之前。
答案 0 :(得分:3)
没有不一致。 MRO基于C3算法,由Chaturvedi解释,更正式地由Simionato解释。
关于:
在第二个例子中它没有达到第三个之前的第一个但是在第三个 第一个例子,它在转到B之前通过A.
由于Third
由
class Third(First):
Third
必须在MRO中First
之前显示。
Chaturvedi用规则解释了这个,
如果A是B的超类,则B优先于A.或者B应该优先 总是出现在所有
__mro__
中的A之前(包含两者)。
在第一个示例中,First
和Third
的等效项为A
和C
。由于C
由
class C(A):
C
出现在MRO的A
之前。
A
之前为什么B
更加复杂。最终归因于C
在B
基础之前列出D
。在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]; 如果此头部不在任何其他列表的尾部,则将其添加到线性化 C并将其从合并中的列表中删除,否则请查看 下一个清单的负责人并接受它,如果它是一个好头。然后重复一遍 操作直到所有课程被删除或不可能 找到好头。在这种情况下,不可能构建 合并后,Python 2.3将拒绝创建C类并将引发一个 异常。
(我的重点解释了为什么Third
必须在First
之前出现。
答案 1 :(得分:0)
不一样,在第一个例子中,所有“爸爸”对象都继承了对象,因为D加载C加载A,并按MRO的顺序,B(由D调用)
第二,所有“dad”对象继承First类。此时,Python最后加载First,因为它需要处理Second和Third。
PS:这是我的理论,但这只是逻辑。以下是您在示例中实施的示例: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__
答案 2 :(得分:-1)
你的第一个继承heirarchy看起来像这样:
D
|\
C B
| |
A |
\|
object
而你的第二个是:
4
|\
2 3
\|
1
|
object
为什么在第二个示例中它不会在
First
之前达到Third
,但在第一个示例中,它会在转到A
之前经过B
?
为什么你会期望这些行为方式相同?查看图表,A
和B
之间的关系与First
和Third
之间的关系完全不同