在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)*不会具有有限形式的多重继承? –