【问题标题】:How do I override a parent class's functions in python?如何在 python 中覆盖父类的函数?
【发布时间】:2011-01-29 20:45:04
【问题描述】:

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

【问题讨论】:

  • 请不要使用所有__ 的。他们很困惑。 Python 中真的没有“私有”。他们让简单的事情看起来很混乱。请使用显示您问题的最小代码示例更新您的问题。
  • 那是我遇到问题的代码......你还想要什么?我知道在 Python 中仍然可以访问“私有”函数和变量,但是在使用类时不会使用所有公共函数会使事情变得更加混乱吗?
  • “那是密码”?什么代码?您能否更新问题以实际提供实际上不起作用的实际代码示例?很难猜测您的代码是什么样的。假设事情很容易;很容易假设错误。 “你还想要什么?”代码。看看你实际上犯了什么错误,而不是我认为你犯了什么错误。
  • human.__pickSide()。这不起作用,因为它没有调用我想要的 human.__pickSide(),而是调用 gambler.__pickSide()。
  • 另外,关于面向对象的谈话,类并没有真正的“功能”。他们有“方法”:P

标签: python inheritance overriding parent


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:
      • 使用 __foo 名称会破坏方法的名称,以便在需要时更麻烦地访问它。我建议永远不要使用它们,这会使测试等事情变得更加顺利。

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

      • 使用单前导下划线表示属性不是类的公共接口的一部分的通用约定,例如_foo。这足以让您的代码清晰地将您的内部详细信息与公共 API 区分开来。

      【讨论】:

        猜你喜欢
        • 2018-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-08
        • 2022-11-03
        • 2022-12-04
        • 1970-01-01
        相关资源
        最近更新 更多