【问题标题】: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”。

有什么限制?

【问题讨论】:

    标签: python inheritance multiple-inheritance concept


    【解决方案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)不会具有有限形式的多重继承?
      猜你喜欢
      • 2016-04-18
      • 2014-03-04
      • 2011-03-17
      • 1970-01-01
      • 2011-03-24
      • 1970-01-01
      • 2011-04-15
      • 2011-02-21
      • 1970-01-01
      相关资源
      最近更新 更多