Python';超级工作吗?

Python';超级工作吗?,python,Python,我有一个类似这样的程序: class A(): def go(self): print("A") class B(A): def go(self): super().go() print("B") class C(A): def go(self): super().go() print("C") class D(A): def go(self): super

我有一个类似这样的程序:

class A():
    def go(self):
        print("A")


class B(A):
    def go(self):
        super().go()
        print("B")


class C(A):
    def go(self):
        super().go()
        print("C")


class D(A):
    def go(self):
        super().go()
        print("D")


class E(B, C, D):
    def go(self):
        super().go()
        print("E")


a  = A()
b = B()
c = C()
d = D()
e = E()

print(e.go())
以下是对此的输出:

A
D
C
B
E
None
我很好奇super()的工作流程,它是如何在B之前打印D,C的,为什么最后没有打印?请详细解释。

如果您致电
帮助(e)
您可以看到:

由于您首先调用
super
,然后调用
print
,因此输出将与
mro
完全相反:

A -> D -> C -> B -> E
如果在
super
调用之前打印了
s,则它将跟随MRO:

E -> B -> C -> D -> A
但是
E.go
不返回任何内容(
return None
是隐式的,如果之前没有其他
return
),因此在调用所有方法后,它将打印
None

如果调用
help(E)
可以看到:

由于您首先调用
super
,然后调用
print
,因此输出将与
mro
完全相反:

A -> D -> C -> B -> E
如果在
super
调用之前打印了
s,则它将跟随MRO:

E -> B -> C -> D -> A


但是
E.go
不返回任何内容(
returnnone
是隐式的,如果之前没有其他
return
),因此在调用所有方法后,它将打印
None

您是否阅读过关于此的大量现有资源?例如你还不明白什么具体内容?@cricket_007因为它是MRO中A之后的下一个,这就是为什么你在实际基类之前加入混音(参见示例)。请参见雷蒙德·海廷格的优秀博客文章《超级被认为是超级》,以及PyCon 2015的演讲:。您可以看到顺序D、C、B,因为这就是Python的方法解析顺序(MRO)的工作方式。@jon我错过了init没有定义,只有e.go()是ranI,我认为我理解了
super
的工作方式,然后这个问题来了,证明我错了。是时候再次避免类似瘟疫的
super
了。你读过关于这方面的大量现有资源吗?例如你还不明白什么具体内容?@cricket_007因为它是MRO中A之后的下一个,这就是为什么你在实际基类之前加入混音(参见示例)。请参见雷蒙德·海廷格的优秀博客文章《超级被认为是超级》,以及PyCon 2015的演讲:。您可以看到顺序D、C、B,因为这就是Python的方法解析顺序(MRO)的工作方式。@jon我错过了init没有定义,只有e.go()是ranI,我认为我理解了
super
的工作方式,然后这个问题来了,证明我错了。是时候避免像瘟疫一样的超级了。是的,我理解MRO的部分。但是B不应该在A之后打印吗?因为B已经完成了它的super()调用,现在它应该打印它自己的部分了吗?@AnmolGulati MRO总是线性的,即使继承不是线性的。因此,当您使用
super()
时,它总是沿着MRO进行。@AnmolGulati问题是python神奇地在
B
A
之间插入
C
D
。在我看来,这是一个糟糕的设计选择。@Rawing好吧,你可能会认为这是一个糟糕的设计选择,但通过这种方式,你将“依赖注入”构建到基本继承中。您不需要像在其他语言中一样依赖框架来处理它。但有时会让人困惑-我总是需要查看
帮助
以确定继承是否也能正常工作:)如果您不想被困惑:避免多重继承-单一继承很容易理解。@MSeifert您能进一步解释一下吗?谢谢。是的,我理解MRO部分。但是B不应该在A之后打印吗?因为B已经完成了它的super()调用,现在它应该打印它自己的部分了吗?@AnmolGulati MRO总是线性的,即使继承不是线性的。因此,当您使用
super()
时,它总是沿着MRO进行。@AnmolGulati问题是python神奇地在
B
A
之间插入
C
D
。在我看来,这是一个糟糕的设计选择。@Rawing好吧,你可能会认为这是一个糟糕的设计选择,但通过这种方式,你将“依赖注入”构建到基本继承中。您不需要像在其他语言中一样依赖框架来处理它。但有时会让人困惑-我总是需要查看
帮助
以确定继承是否也能正常工作:)如果您不想被困惑:避免多重继承-单一继承很容易理解。@MSeifert您能进一步解释一下吗?谢谢