【问题标题】:Calling super().method() in a subclass that does not override method在不覆盖方法的子类中调用 super().method()
【发布时间】:2019-05-29 18:50:30
【问题描述】:

superPython documentation 声明:

这对于访问已在类中被覆盖的继承方法很有用。

覆盖method的子类中调用super().method()有什么意义吗?

对我来说没有,因为调用self.method() 是等价的,也就是说,继承将在self 的超类中使用相同的type(self).__mro__ 方法解析顺序(由@ 给出self 的超类层次结构中的 987654322@)比 super

所以对我来说,super 在这种情况下很有用:

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

class B:
    pass

class C(B, A):
    def f(self):
        super().f()
        print("C")

C().f()  # prints A C

但不在这个:

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

class B:
    pass

class C(B, A):
    def g(self):
        super().f()  # should be just self.f()
        print("C")

C().g()  # prints A C

【问题讨论】:

  • 视情况而定。请记住,在C 中,您不知道super() 将引用哪个类。这是在运行时确定的,self 可能是您不知道的C 的某个后代的实例。 那个类可能会覆盖f
  • (也就是说,您的“无用”示例实际上比无用更糟糕,因为它可能会主动阻止首先调用正确的方法。)
  • @chepner 是的,super().f()C 中你不知道它会引用哪个类,但self.f() 也不知道,是吗?
  • 但是您并没有主动跳过 self.f() 的实现。你给type(f).f 一个运行的机会,让它决定是否需要调用它覆盖的方法。
  • @chepner 我想你的意思是type(self).f。好的,我明白了:如果我创建了 C 的子类 D 并在其中覆盖了 f,则调用 D.g 将调用 D.fself.f()A.fsuper().f(),对吗?

标签: python inheritance overriding super method-resolution-order


【解决方案1】:

正如@chepner 所指出的,在不覆盖method 的子类中调用super().method()等同于调用self.method()。差异出现在覆盖method 的该子类的子类中。

比较:

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

class B:
    pass

class C(B, A):
    def g(self):
        super().f()  # == super(C, self).f(), so lookup starts after C in type(self).__mro__
        print("C")

class D(C):    
    def f(self):
        print("D")

D().g()  # prints A C, since D.__mro__ == (D, C, B, A, object)

与:

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

class B:
    pass

class C(B, A):
    def g(self):
        self.f()  # lookup starts at the beginning in type(self).__mro__
        print("C")

class D(C):
    def f(self):
        print("D")

D().g()  # prints D C, since D.__mro__ == (D, C, B, A, object)

【讨论】:

    猜你喜欢
    • 2013-10-24
    • 2012-05-01
    • 2020-09-20
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 2023-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多