我正在尝试获取包含super()函数的以下python代码的输出。
class A(object):
def go(self):
print("go A go!")
def stop(self):
print("stop A stop!")
def pause(self):
raise Exception("Not Implemented")
class B(A):
def go(self):
super(B, self).go()
print("go B go!")
class C(A):
def go(self):
super(C, self).go()
print("go C go!")
def stop(self):
super(C, self).stop()
print("stop C stop!")
class D(B,C):
def go(self):
super(D, self).go()
print("go D go!")
def stop(self):
super(D, self).stop()
print("stop D stop!")
def pause(self):
print("wait D wait!")
class E(B,C): pass
a = A()
b = B()
c = C()
d = D()
e = E()
#Find output of below function calls
d.go()
b.stop()
我的问题是:
为什么d.go()
的输出为:
go A go!
go C go!
go B go!
go D go!
不应该有一个额外的“去吧!”在输出中作为B类和C类都是使用super()函数调用基类A的方法?
由于B类中没有stop()函数,为什么b.stop()
返回“停止停止!”而不是提出错误?
答案 0 :(得分:0)
super
没有给你一条"直线"结果是每个子类中的所有祖先按顺序排列。
相反,它确实被认为是做正确的事情"当涉及到多重继承 - 以及"正确的事情的基本部分"正是避免了一个超类中的方法被多次调用。
因此,首先,无论何时在Python中创建一个类,该类都会获得__mro__
属性(方法解析顺序)。第一类始终是类本身,最后一个始终是object
。
super()
将按照它们在__mro__
中出现的顺序搜索类,以便检索属性,方法或超类属性或方法。 This is the documente describing the MRO linearization algorithm, that started to beused with Python 2.3 and is in use up to today 。
根据这些规则,您会发现D类的MRO是(D, B, C,A, object)
,如果方法的原始调用位于D
对象中,则为super
在B
中方法的实现中遇到它会调用C
实现,因为C是D __mro__
中的下一个类。上面链接的文档有理由和更多示例,但TL; DR:这确保每个上游类都有机会被调用至少一次,如果涉及的所有方法都在协作中使用super
方式。
至于
由于B类中没有stop()函数,为什么b.stop()是 返回"停止停止!"而不是提出错误?
这是基本的继承,不需要人理解Python super
的细节:如果在子类中没有覆盖它,则使用超类方法。