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

发布于 2024-08-26 03:22:17 字数 130 浏览 6 评论 0原文

我在父类中有一个私有方法 def __pickSide(self): ,我想在子类中重写该方法。然而子类仍然调用继承的def __pickSide(self):。我怎样才能重写该函数?子类的函数名与父类的函数名完全相同。

I have a private method def __pickSide(self): in a parent class that I would like to override in the child class. However, the child class still calls the inherited def __pickSide(self):. How can I override the function? The child class's function name is exactly the same as the parent's function name.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

初见终念 2024-09-02 03:22:17

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

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

Let's look at the easiest example:

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)

The disassembly is as follows:

  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

As you can see, Python mangles function names that begin with two underscores (and accesses to such names!!) to a name that includes the class name - in this case _A__pick and _B__pick). That means that the class in which a function is defined determines which of the __pick methods is called.

The solution is simple, avoid pseudo-private methods by removing the double underscores. For example, use _pick instead of __pick.

十年不长 2024-09-02 03:22:17

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

The problem you're seeing is that the double underscores mangle the function name even in calls. This prevents polymorphism from working properly since the name it is mangled to is based on the name of the class the method is defined in, and not the name of the class of the object that is being referenced. Replacing the double underscores with something else will solve this.

谜兔 2024-09-02 03:22:17
  • 使用 __foo 名称会破坏方法的名称,使您在需要时访问它变得更加麻烦。我建议永远不要使用它们,这使得测试之类的事情变得更加顺利。

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

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

  • Using __foo names mangles the name of the method to make it more hassle to access it when you need to. I would recommend never using them, which makes things like testing go more smoothly.

  • There is no private in Python, and if there was, it would prevent you from doing this anyhow. (This is the point of private stuff in languages that have it.)

  • The common convention to indicate that an attribute is not part of the public interface of a class it to use a single leading underscore, like _foo. This is sufficient for making your code clear separating your internal details from your public API.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文