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中的每个类。您的代码链接了调用,因为每个被调用的方法都有另一个调用。Top.m()
调用super().m()
,后者解析为MixinB.m()
;后者又使用super()
,以此类推mixin a
在mixin b
之前打印,因为您在super()
调用之后打印,所以MRO中最后一个元素首先执行。super()
调用只是另一个方法调用,因此在完成super().m()
调用之前,不会执行此类调用之后的print
语句。你知道吗您的MRO如下:
所以自然地
Base.m()
被称为最后一个,首先打印,然后是MixinA
,然后是MixinB
,最后是Top
。你知道吗请注意,
self
的MRO被用作第一个参数,而不是作为第一个参数传递给super()
的类;因此,对于任何给定实例,MRO在层次结构中的所有调用中都是稳定的。你知道吗如果您希望print语句按照MRO调用链接的顺序执行,则必须将
print
语句放在调用MRO中下一个m()
方法之前。你知道吗这里不涉及尝试,您的呼叫顺序是
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'
并返回给调用者。你知道吗打印顺序与调用顺序相反,因为您是在超级调用链之后执行它们的。你知道吗
相关问题 更多 >
编程相关推荐