如何从基类调用重写的方法?

9 投票
2 回答
12374 浏览
提问于 2025-04-16 21:04

Dive into Python -

Python的创始人Guido这样解释方法重写:“派生类可以重写它们基类的方法。因为在调用同一个对象的其他方法时,方法之间没有特别的权限,所以一个基类的方法如果调用了同样基类中定义的另一个方法,实际上可能会调用到一个派生类中重写了它的方法。(对于C++程序员来说:Python中的所有方法实际上都是虚拟的。)”如果这让你感到困惑(我也是一头雾水),可以随意忽略。我只是想分享一下。

我正在尝试找一个例子来说明:基类的方法调用了同样基类中定义的另一个方法,实际上可能会调用到一个派生类中重写了它的方法

class A:      
  def foo(self): print 'A.foo'      
  def bar(self): self.foo()                  

class B(A):      
  def foo(self): print 'B.foo'     

if __name__ == '__main__': 
  a = A()                
  a.bar()                   # echoes A.foo
  b = B()
  b.bar()                   # echoes B.foo

...但这两个似乎有点明显。

我是不是漏掉了引用中提到的某些内容?


更新

在原始代码中修正了调用a.foo()(而不是a.bar())和b.foo()(而不是b.bar())的拼写错误。

2 个回答

9

请注意,这在Python 3.6中对私有方法是无效的:

class A:      
  def __foo(self): print 'A.foo'      
  def bar(self): self.__foo()                  

class B(A):      
  def __foo(self): print 'B.foo'     

if __name__ == '__main__': 
  a = A()                
  a.bar()                   # echoes A.foo
  b = B()
  b.bar()                   # echoes A.foo, not B.foo

我花了一个小时才搞明白这个原因

8

是的,你漏掉了这一点:

b.bar()   # echoes B.foo

B 自己没有 bar 这个方法,只有从 A 继承来的。Abar 方法会调用 self.foo,但在 B 的实例中,实际上调用的是 Bfoo,而不是 Afoo

让我们再看看你引用的内容:

一个基类的方法如果调用了 同一个基类中定义的另一个方法, 可能最终会调用一个派生类的方法, 而这个方法覆盖了它。

简单来说:

barA 的方法,基类)会调用 self.foo,但实际上可能会调用一个派生类的方法, 而这个方法覆盖了它(B.foo 覆盖了 A.foo)。

撰写回答