PYTHON:公共,私有(单下划线)和私有(双下划线)方法的虚方法行为差异

时间:2013-01-30 19:12:19

标签: python virtual-functions private-methods

我在python中试用了NVI(非虚拟接口)成语,并注意到私有(双下划线)方法似乎不是虚拟的。

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中的所有方法都是虚拟的。)”。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

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