如何在python中重写父类的函数?

2024-06-08 22:36:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我在父类中有一个私有方法def __pickSide(self):,我想在子类中重写它。但是,子类仍然调用继承的def __pickSide(self):。如何重写函数?子类的函数名与父类的函数名完全相同。


Tags: 方法函数selfdef子类父类pickside
3条回答
  • 使用__foonames会损坏方法的名称,以便在需要时更容易访问它。我建议不要使用它们,这会让测试变得更加顺利。

  • Python中没有private,如果有的话,无论如何都会阻止您这样做。(这是拥有它的语言中的私有内容的要点。)

  • 表示属性不是类的公共接口的一部分的通用约定,它使用单前导下划线,如_foo。这足以使代码清晰地将内部细节与公共API分离。

您看到的问题是,即使在调用中,双下划线也会损坏函数名。这会阻止多态性正常工作,因为它被损坏的名称是基于在其中定义方法的类的名称,而不是所引用对象的类的名称。用其他方法替换双下划线可以解决这个问题。

让我们看看最简单的例子:

from dis import dis

class A(object):
  def __pick(self):
      print "1"

  def doitinA(self):
      self.__pick()

class B(A):
  def __pick(self):
      print "2"

  def doitinB(self):
      self.__pick()

b = B()
b.doitinA() # prints 1
b.doitinB() # prints 2

dis(A.doitinA)
print
dis(B.doitinB)

拆卸步骤如下:

  8           0 LOAD_FAST                0 (self)
              3 LOAD_ATTR                0 (_A__pick)
              6 CALL_FUNCTION            0
              9 POP_TOP
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE

 15           0 LOAD_FAST                0 (self)
              3 LOAD_ATTR                0 (_B__pick)
              6 CALL_FUNCTION            0
              9 POP_TOP
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE

如您所见,Python会篡改以两个下划线开头的函数名(并访问这些名称!!)包含类名的名称-在本例中是_A__pick_B__pick)。这意味着定义函数的类决定调用哪个__pick方法。

解决方案很简单,通过删除双下划线来避免伪私有方法。例如,使用_pick,而不是__pick

相关问题 更多 >