【问题标题】:calling an overridden method from base class?从基类调用重写的方法?
【发布时间】:2011-07-08 06:43:15
【问题描述】:

Dive into Python -

Python 的原作者 Guido 以这种方式解释方法覆盖:“派生类可能会覆盖其基类的方法。因为方法在调用同一对象的其他方法时没有特殊权限,因此基类的方法可以调用在同一个基类中定义的另一个方法,实际上可能最终调用覆盖它的派生类的方法。(对于 C++ 程序员:Python 中的所有方法实际上都是虚拟的。)“如果这对你没有意义(这让我很困惑),请随意忽略它。我只是想我会把它传下去。

我试图找出一个例子:一个基类的方法调用同一个基类中定义的另一个方法,实际上可能最终调用一个覆盖它的派生类的方法 em>

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())的错字

【问题讨论】:

  • 获取父母b.__class__.__mro__[1].hi(A())的肮脏黑客
  • @Jakob:为什么不super
  • @Eli 在 python2.6.6 上返回 NULL 吗? :S

标签: python


【解决方案1】:

是的,你错过了这个:

b.bar()   # echoes B.foo

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

让我们再看看你的报价:

调用基类的方法 同一个定义的另一种方法 基类,实际上可能最终调用 派生类的方法 覆盖它

翻译:

barA的方法,基类) 致电self.foo,但实际上可能会结束 调用派生类的方法 覆盖它(B.foo 覆盖A.foo)

【讨论】:

  • 哎呀!我犯了一个错误,我的意思是b.bar()在原始代码中两次:(而且它似乎仍然很明显,因为B继承了A,它也有bar()但我看不到它。此外,因为我明确传递@987654340 @很明显是B'对象)
  • @Vaibhav:如果这看起来很明显,那么很好 - 还有什么?顺便说一句,在 C++ 中,除非方法是虚拟的,否则它不会以这种方式工作。所以它在全球范围内并不明显。在 Python 中,从 C++ 的角度来看,所有方法都是虚拟的
  • 我应该更改我的代码以反映原始问题吗? (但我不想粗鲁,因为你的答案对应这个)
  • @Vaibhav:我想您可以更改它,只需使用“更新”明确说明即可。重要的是希望你不再迷茫
【解决方案2】:

注意,这不适用于 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

我花了一个小时找出原因

【讨论】:

  • 感谢您的评论,我只花了 10 分钟搜索相同的内容!
  • 这实际上是双下划线名称修改的唯一目的
  • 这是什么原因?
猜你喜欢
  • 2012-12-12
  • 2011-06-17
  • 1970-01-01
  • 2011-01-18
  • 1970-01-01
  • 2023-03-12
  • 2013-05-06
  • 2017-05-05
相关资源
最近更新 更多