【问题标题】:Python's super() working?Python 的 super() 工作?
【发布时间】:2017-09-20 07:06:36
【问题描述】:

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

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 的,为什么最后打印的是 None?详细解释将不胜感激。

【问题讨论】:

标签: python


【解决方案1】:

如果您拨打help(e),您可以看到method resolution order

>>> e = E()
>>> help(e)
class E(B, C, D)
 |  Method resolution order:
 |      E
 |      B
 |      C
 |      D
 |      A
 |      builtins.object

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

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

如果您在 super 调用之前有 prints,它将遵循 MRO:

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

但是E.go 不返回任何内容(如果之前没有其他returnreturn None 是隐含的)所以它会在调用所有方法后打印None

【讨论】:

  • 是的,我了解 MRO 部分。但是不应该在 A 之后打印 B,因为 B 已经完成了它的 super() 调用,现在它应该打印自己的部分吗?
  • @AnmolGulati 即使继承不是线性的,MRO 也始终是线性的。因此,当您使用 super() 时,它始终在 MRO 中。
  • @AnmolGulati 事情是python神奇地插入CDBA之间。这是 IMO 的一个糟糕的设计选择。
  • @Rawing 好吧,您可能认为这是一个糟糕的设计选择,但这样您就可以将“依赖注入”内置到基本继承中。您不需要像其他语言一样依赖框架来处理它。但有时会令人困惑——我总是需要检查help 以确定继承是否也按预期工作:) 如果你不想混淆:避免多重继承——单继承很容易理解。
  • @MSeifert 你能再解释一下吗?谢谢。
猜你喜欢
  • 2011-01-17
  • 2018-01-27
相关资源
最近更新 更多