Python 支持有限形式的多重继承。以啥方式限制?
Posted
技术标签:
【中文标题】Python 支持有限形式的多重继承。以啥方式限制?【英文标题】:Python supports a limited form of multiple inheritance. In what way limited?Python 支持有限形式的多重继承。以什么方式限制? 【发布时间】:2012-05-27 07:33:11 【问题描述】:在 python 教程中说“Python supports a limited form of multiple inheritance”。
有什么限制?
【问题讨论】:
【参考方案1】:除了@Matt Anderson 的回答,我认为这些限制实际上是针对旧样式类(Python 2.6 still addresses 的教程)。
在 Python 3 教程中,文本现在是:Python supports a form of multiple inheritance as well。
【讨论】:
【参考方案2】:我不确定 python 教程的作者所指的限制是什么,但我猜这部分与在 python 中实现方法/属性查找的方式有关(“方法解析顺序”或MRO)。 Python使用C3 superclass linearization机制;这是为了处理所谓的“The Diamond Problem”。
在您的类层次结构中引入多重继承后,任何给定的类都没有一个可以继承的潜在类,它只有“MRO 中的下一个类”,即使对于那些期望它们继承的类也是如此。特别是从某个类继承。
例如,如果 class A(object)
、class B(A)
、class C(A)
和 class D(B, C)
,则类 D
的 MRO 为 D->B->C->A
。 B 类可能已经被编写,可能是,认为它是 A 的后代,当它对自己调用 super()
时,它会在 A 上获得一个方法。但这不再是正确的;当 B 调用 super()
时,它会在 C 上获得一个方法,如果它存在的话。
如果您在被覆盖的方法中更改方法签名,这可能是一个问题。 B 类在调用 super 时期望来自 A 类的方法的签名,而是从 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。当它调用 super 时,事情就爆炸了:
[<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)不会具有有限形式的多重继承?以上是关于Python 支持有限形式的多重继承。以啥方式限制?的主要内容,如果未能解决你的问题,请参考以下文章