使用super()函数的模糊输出

时间:2017-10-30 17:59:22

标签: python

我正在尝试获取包含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()

我的问题是:

  1. 为什么d.go()的输出为:

    go A go!
    go C go!
    go B go!
    go D go!
    

    不应该有一个额外的“去吧!”在输出中作为B类和C类都是使用super()函数调用基类A的方法?

  2. 由于B类中没有stop()函数,为什么b.stop()返回“停止停止!”而不是提出错误?

1 个答案:

答案 0 :(得分:0)

Python中的

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对象中,则为superB中方法的实现中遇到它会调用C实现,因为C是D __mro__中的下一个类。上面链接的文档有理由和更多示例,但TL; DR:这确保每个上游类都有机会被调用至少一次,如果涉及的所有方法都在协作中使用super方式。

至于

  

由于B类中没有stop()函数,为什么b.stop()是   返回"停止停止!"而不是提出错误?

这是基本的继承,不需要人理解Python super的细节:如果在子类中没有覆盖它,则使用超类方法。