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

Posted

技术标签:

【中文标题】“__”函数的Python奇怪的覆盖行为【英文标题】:Python strange override behaviour for "__" functions 【发布时间】:2014-12-20 06:17:35 【问题描述】:

我在 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“__”函数的行为是否正常?

【问题讨论】:

这是不使用__foo名称的众多充分理由之一。它们不是“私人的”,它们只是令人困惑和奇怪。 【参考方案1】:

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

带有前导双下划线的名称被“损坏”;以类的名称为前缀,明确以防止名称冲突与子类。

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

__* 类私有名称。此类别中的名称在类定义的上下文中使用时,会被重写为使用错位形式以帮助避免基类和派生类的“私有”属性之间的名称冲突

强调我的

另见表达式文档的Identifiers section:

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

【讨论】:

以上是关于“__”函数的Python奇怪的覆盖行为的主要内容,如果未能解决你的问题,请参考以下文章

Python元类的__new__方法中的奇怪行为[重复]

我是不是必须覆盖 python 的列表函数?

multiprocessing.Queue 奇怪的 python 行为

调用fread后奇怪的printf行为

CUDA 内核的奇怪行为

在外部覆盖 python 模块函数