2012-05-20 39 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)*不會具有有限形式的多重繼承? –