了解钻石继承中的super()

时间:2019-05-26 17:11:58

标签: python

我正在学习python,并开始在继承中学习MRO。

我已经阅读了super的用法及其使用方式,但是我无法理解以下问题。如果不是超级,我知道B被调用。 D-> B-> C-> A,但是当添加超级时,我不知道为什么输出是这样的

class A:
    def test(self):
        print("test of A called")
class B(A):
    def test(self):
        print("test of B called")
        super().test()
class C(A):
    def test(self):
        print("test of C called")
        super().test()
class D(B, C):
    def test2(self):
        print("test of D called")
obj=D()
obj.test()

输出

test of B called
test of C called
test of A called

请帮助我了解super在这里的功能。

2 个答案:

答案 0 :(得分:8)

super()将按照Python遵循C3线性化(https://en.wikipedia.org/wiki/C3_linearization)的方法解析顺序进入下一类:在父级之前先调用子级,在父级之前先调用子级已设置。

因此,如果您在类D中调用方法,则MRO为D-> B-> C-> A,但例如如果您最初在类B中调用它,则MRO为B-> A。

这样更清楚吗?

编辑:因此在您的示例中: 您调用了不存在的D.test(),因此它被委派给B.test(),后者打印一个字符串,然后调用super()。由于如上所述的MRO,在这种情况下B的super()是C,因此接下来调用C.test(),然后最终调用A.test()

答案 1 :(得分:1)

这是您的继承层次结构:

inheritance diagram

final String action = intent.getAction(); switch (action) { case BluetoothDevice.ACTION_FOUND: final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); final String deviceName = device.getName(); final String extraName = intent.getStringExtra(BluetoothDevice.EXTRA_NAME); if (deviceName.equals(extraName)) { // Always true? 具有两个父级外,大多数类仅从一个父级类继承。尽管没有明确说明,D隐式继承自A

对于任何类的对象,请按照图的方向朝根方向倒退,以查看Python检查类以查找您所调用的方法的顺序。例如,将以objectDDBC的顺序访问A实例。 object之前的B在这里,因为它在类定义中排名第一。

您似乎已经稍微改变了方法名称(Ctest2),这是一种很好的做法,以查看test是否存在(如何解决)在超类的各种组合中。

test是一个明确的请求,它是“从当前对象的超类调用给定方法。”

为进一步阅读,搜索词“ Python MRO”应该能很好地为您服务,并带给您excellent walkthroughs的数量。