【问题标题】:PYTHON: virtual method behavior differences for public, private(single underscore) and private(double underscore) methodsPYTHON:公共、私有(单下划线)和私有(双下划线)方法的虚拟方法行为差异
【发布时间】:2013-01-14 17:35:19
【问题描述】:

我在 python 中尝试了 NVI(Non-Virtual Interface) Idiom,并注意到私有(双下划线)方法似乎不像虚拟。

class A(object):
    def a(self):
        print "in A.a"
    self.b()
    self.__b()
    self._b()

def _b(self):
    print "in A._b"

def __b(self):
    print "in A.__b"

def b(self):
    print "in A.b"

class B(A):
def __b(self):
    print "in B.__b"

def b(self):
    print "in B.b"

def _b(self):
    print "in B._b"

>>> a=A()
>>> b=B()
>>> a.a()
in A.a
in A.b
in A.__b
in A._b
>>> b.a()
in A.a
in B.b
in A.__b
in B._b

我猜这可能是因为双下划线方法的名称修改,但这是违反直觉的。此外,python 文档“(对于 C++ 程序员:Python 中的所有方法实际上都是虚拟的。)”引起了混淆。

【问题讨论】:

  • 你应该修复代码缩进,不清楚你的意图是什么

标签: python virtual-functions private-methods


【解决方案1】:

您的分析是正确的。这是由于名称重整,这实际上使 A.__bB.__b 无关(因为它们具有不同的重整名称)。

【讨论】:

    【解决方案2】:

    正如the documentation 所说,双前导下划线方法适用于类私有成员。它们对于使用它们的特定类是私有的,而不是它的类继承子树。这就是重点:它们是为特定于类的变量而设计的,您希望覆盖子类定义或访问子类方法的值。

    您是正确的,名称修改是您描述的行为的来源。所有 Python 方法确实是虚拟的,因为它们可以被覆盖。双下划线方法只是通过修改名称使从类外部的访问变得更加困难。您可以通过在类B 中定义方法_A__b 来覆盖A.__b。这将是一个坏主意,因为它首先会破坏使用双下划线的目的,但这是可能的。

    【讨论】:

    • 这是否是一个坏主意是一个观点问题;-) -- 正如成语所说,“我们在这里都是同意的成年人”。但这当然不是未经深思熟虑就应该完成的事情。
    猜你喜欢
    • 2019-06-23
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 2021-10-07
    • 2018-06-30
    • 2018-11-16
    相关资源
    最近更新 更多