在python教程中有人說「Python supports a limited form of multiple inheritance」。Python支持多重繼承的有限形式。以什麼方式有限?
有什麼限制?
在python教程中有人說「Python supports a limited form of multiple inheritance」。Python支持多重繼承的有限形式。以什麼方式有限?
有什麼限制?
除了@Matt Anderson的回答,我認爲這個限制實際上是針對舊的風格類(其教程爲Python 2.6 still addresses)。
在Python 3教程中,文本現在是:Python supports a form of multiple inheritance as well。
我不知道該蟒蛇教程的作者是指什麼限制,但我估計它有一部分與該方法/屬性查找在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()
),並且「菱形」不必僅出現在類層次結構的根部。
所有這一切都是真實的,但任何具有多重繼承的語言都必須處理這些問題。如果我們假設你的答案是正確的,那麼哪種語言(與MI)*不會具有有限形式的多重繼承? –