7

我对这种行为有点困惑(使用 python 3.2):

class Bar:
    pass

bar = Bar()
bar.__cache = None
print(vars(bar))        # {'__cache': None}

class Foo:
    def __init__(self):
        self.__cache = None

foo = Foo()
print(vars(foo))        # {'_Foo__cache': None}

我已经阅读了一些关于双下划线如何导致属性名称“损坏”的内容,但我希望在上述两种情况下都会出现相同的名称损坏。

对象名称前的单下划线和双下划线是什么意思?

有什么想法吗?

4

2 回答 2

12

名称修改发生在class语句的评估期间。在 的情况下Bar__cache属性没有被定义为类的一部分,而是在事后添加到特定对象中。

(实际上,这可能不完全正确。在评估__new__方法期间可能会发生名称修改;我不知道。但无论如何,您__cache是显式添加到单个对象中的,而不是由类代码添加的。)

于 2012-11-21T16:57:35.433 回答
9

文档

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

您在定义类后分配您的属性

于 2012-11-21T16:56:24.193 回答