【问题标题】:Does super try each class in MRO超级尝试MRO中的每个课程吗
【发布时间】:2016-07-19 08:26:37
【问题描述】:
class Base(object):
    def m(self):
        print 'base'


class MixinA(Base):
    def m(self):
        super(MixinA, self).m()
        print 'mixin a'


class MixinB(Base):
    def m(self):
        super(MixinB, self).m()
        print 'mixin b'


class Top(MixinB, MixinA, Base):
    def m(self):
        super(Top, self).m()
        print 'top'


t = Top()
t.m()

打印出来:

base
mixin a
mixin b
top

我对很多事情感到惊讶。 Top 的第一个 MRO 是 (<class 'Top'>, <class 'MixinB'>, <class 'MixinA'>, <class 'Base'>, <type 'object'>)

  1. 为什么mixin a 出现在mixin b 之前?
  2. super 是否尝试 MRO 中的每个类(与返回找到的第一个属性时搜索属性不同)?

【问题讨论】:

    标签: python oop multiple-inheritance super


    【解决方案1】:

    不,super() 不会“尝试” MRO 中的每个课程。您的代码将调用链接,因为每个调用的方法都有另一个 super() 调用。 Top.m() 调用super().m(),解析为MixinB.m();反过来又使用super(),等等。

    mixin amixin b 之前打印,因为您是在super() 调用之后打印,因此首先执行MRO 中的last 元素。 super() 调用只是另一个方法调用,因此在这样的调用之后的print 语句在super().m() 调用完成之前不会被执行。

    您的 MRO 如下:

    >>> type(t).__mro__
    (<class '__main__.Top'>, <class '__main__.MixinB'>, <class '__main__.MixinA'>, <class '__main__.Base'>, <type 'object'>)
    

    所以Base.m() 很自然地被最后调用并首先打印,然后是MixinA,然后是MixinB,最后一个打印是Top

    注意使用self 的MRO,而不是作为第一个参数传入super() 的类;因此,MRO 在任何给定实例的层次结构中的所有调用中都是稳定的。

    如果您希望打印语句按照 MRO 调用的链接顺序执行,则必须将 print 语句放在调用 MRO 中的下一个 m() 方法之前 .

    【讨论】:

      【解决方案2】:

      这里不涉及尝试:您的调用顺序是

      • Top.m() 调用super(Top, self).m(),即MixinB.m()

      • MixinB.m() 立即调用super(MixinB, self).m(),当使用type(self) == Top 调用时,MixinA.m()super() 使用 self 对象的 MRO,因此我们需要查看 Top,而不是独立的 MixinB

      • MixinA.m() 调用super(MixinA, self).m(),即Base.m()

      那时没有更多的超级调用,所以

      • Base 执行 print 'base' 并返回(到 MixinA.m()
      • MixinA.m() 打印 'mixin a' 并返回(到 MixinB.m()
      • MixinB.m() 打印 'mixin b' 并返回(到 Top.m())。
      • Top.m() 打印 'top' 并返回给调用者。

      打印是反向调用顺序,因为您是在超级调用链之后执行它们。

      【讨论】:

      • super(MixinB).m() 不调用MixinA.m()
      • @Marii:是的,确实如此。 MixinAtype(self) 的 MRO 中的下一个类。
      • @Marii:不要混淆。我们使用 Top 的 MRO 而不是 MixinB 的 MRO 作为独立类。如图所示,当与Top 混合时,super(MixinB, self)(与type(self) == Top)实际上是MixinA
      猜你喜欢
      • 2014-06-04
      • 1970-01-01
      • 2017-06-12
      • 1970-01-01
      • 2013-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-25
      相关资源
      最近更新 更多