“__”函数的Python奇怪覆盖行为

时间:2014-10-24 11:57:47

标签: python function private

我发现Python中的“奇怪”行为覆盖了“__”函数

class A(object):

    def foo1(self):
        print "foo1 A"
        self.test1()

    def foo2(self):
        print "foo2 A"
        self.__test2()

    def test1(self):
        print "test1 A"

    def __test2(self):
        print "test2 A"

class B(A):
    def test1(self):
        print "test1 B"

    def __test2(self):
        print "test2 B"

ia = A()
ib = B()
ib.foo1()
ib.foo2()

结果如下:

foo1 A
test1 B
foo2 A
test2 A

而不是:

foo1 A
test1 B
foo2 A
test2 B

是Python“__”函数的正常行为吗?

1 个答案:

答案 0 :(得分:10)

您看到的行为是在类属性或方法中使用前导双下划线名称的声明的意图

带有前导双下划线的名称被“损坏”;具有前缀类的名称,显式地防止名称冲突与子类。

请参阅参考文档中的Reserved classes of identifiers

  

__*
  类私有名称。在类定义的上下文中使用时,此类别中的名称将被重写,以使用损坏的表单来帮助避免基类和派生类的“私有”属性之间的名称冲突

强调我的

另请参阅表达式文档的Identifiers section

  

私有名称修改:当在类定义中以文本方式出现的标识符以两个或多个下划线字符开头且不以两个或多个下划线结尾时,它被视为该类的私有名称。在为其生成代码之前,将私有名称转换为更长的形式。转换将在名称前面插入类名,删除前导下划线并插入单个下划线。例如,名为__spam的类中出现的标识符Ham将转换为_Ham__spam。此转换独立于使用标识符的语法上下文。如果转换后的名称非常长(超过255个字符),则可能会发生实现定义的截断。如果类名仅由下划线组成,则不进行转换。