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 中的每个类(不同于在返回找到的第一个属性时搜索属性)?
最佳答案
不,super()
不会“尝试”MRO 中的每个类。您的代码链接调用,因为调用的每个方法都有另一个 super()
调用它。 Top.m()
电话 super().m()
,解析为 MixinB.m()
;反过来使用 super()
再次等等
mixin a
在 mixin b
之前打印因为你在 之后 super()
打印调用,因此首先执行 MRO 中的 last 元素。 super()
call 只是另一个方法调用,所以 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
在 调用下一个 m()
之前的语句MRO 中的方法。
关于python - super 会尝试 MRO 中的每个类吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38453165/