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'>)
mixin a
出现在mixin b
之前?super
是否尝试MRO中的每个类(与返回找到第一个属性时搜索属性不同)?答案 0 :(得分:7)
不,super()
没有尝试&#39; MRO中的每个班级。您的代码链这些调用,因为每个调用的方法都包含另一个 super()
调用。 Top.m()
调用super().m()
,解析为MixinB.m()
;然后又使用super()
等等。
mixin a
之前打印 mixin b
,因为您在<{strong> 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调用的链接顺序执行打印语句,那么您必须在调用下一个{{1}之前放置print
语句 MRO中的方法。
答案 1 :(得分:4)
此处没有尝试:您的致电订单是
Top.m()
致电super(Top, self).m()
MixinB.m()
。
MixinB.m()
在使用super(MixinB, self).m()
调用时立即调用MixinA.m()
type(self) == Top
。 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'
并返回给来电者。打印件处于反向调用顺序,因为您正在超级调用链之后执行它们。