2012-05-20 38 views

回答

12

我不知道该蟒蛇教程的作者是指什么限制,但我估计它有一部分与该方法/属性查找在Python(以下简称“方法解析顺序”实施的方式做或MRO)。 Python使用C3 superclass linearization机制;这是为了处理所谓的“The Diamond Problem”。

将多重继承引入类层次结构后,任何给定的类都没有一个继承的潜在类,它只具有“MRO中的下一个类”,即使对于期望他们特别是继承了某一类。

例如,如果class A(object)class B(A)class C(A),和class D(B, C),则MRO为D类是D->B->C->A。 B类可能已经写过,可能是,认为它是从A下降的,当它自己调用super()时,它会在A上得到一个方法。但是这不再是真的;当B调用super()时,如果它存在,它将在C上得到一个方法。

如果您在重写的方法中更改方法签名,这可能是一个问题。 B类,当它调用super时,期望从A类方法签名,而是从C获得一个方法,C方法可能没有那个签名(并且可能会或可能不会从B类的角度实现所需的行为)。

class A(object): 
    def __init__(self, foo): 
     print "A!" 

class B(A): 
    def __init__(self, foo, bar): 
     print "B!" 
     super(B, self).__init__(foo) 

class C(A): 
    def __init__(self, foo, baaz): 
     print "C!" 
     super(C, self).__init__(foo) 

class D(B, C): 
    def __init__(self, foo, bar): 
     print "D!" 
     super(D, self).__init__(foo, bar) 

print D.mro() 
D("foo", "bar") 

在此代码示例,类B和C都合理地延长A,并改变了他们__init__签名,但正确地调用其超预期的签名。但是,当你做出d这样,B的有效的“超”变成C,而不是A.当它调用超,东西炸掉:

[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>] 
D! 
B! 
Traceback (most recent call last): 
    File "/tmp/multi_inherit.py", line 22, in <module> 
    D("foo", "bar") 
    File "/tmp/multi_inherit.py", line 19, in __init__ 
    super(D, self).__init__(foo, bar) 
    File "/tmp/multi_inherit.py", line 9, in __init__ 
    super(B, self).__init__(foo) 
TypeError: __init__() takes exactly 3 arguments (2 given) 

这同样的事情会发生其他方法以及(如果他们呼叫super()),并且“菱形”不必仅出现在类层次结构的根部。

+7

所有这一切都是真实的,但任何具有多重继承的语言都必​​须处理这些问题。如果我们假设你的答案是正确的,那么哪种语言(与MI)*不会具有有限形式的多重继承? –