super()表示多重继承不一致

时间:2013-04-23 18:09:27

标签: python inheritance

我有两个多重继承的例子看起来是一样的,但我得到了不同的结果顺序。

来自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 ExampleCallisto

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之前。

3 个答案:

答案 0 :(得分:3)

没有不一致。 MRO基于C3算法,由Chaturvedi解释,更正式地由Simionato解释。


关于:

  

在第二个例子中它没有达到第三个之前的第一个但是在第三个   第一个例子,它在转到B之前通过A.

由于Third

定义
class Third(First):

Third必须在MRO中First之前显示。

Chaturvedi用规则解释了这个,

  

如果A是B的超类,则B优先于A.或者B应该优先   总是出现在所有__mro__中的A之前(包含两者)。

在第一个示例中,FirstThird的等效项为AC。由于C

定义
class C(A):

C出现在MRO的A之前。

A之前为什么B更加复杂。最终归因于CB基础之前列出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

operative rule正在:

  

取第一个清单的头部,即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

为什么你会期望这些行为方式相同?查看图表,AB之间的关系与FirstThird之间的关系完全不同