6

我有点受这种行为混淆(使用Python 3.2)重整:Python的双下划线

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} 

我已经阅读了关于双下划线怎么引起属性名称是“错位”了一点,但我会期待同一个名字 - 在上述两种情况下都会发生。

What is the meaning of a single- and a double-underscore before an object name?

任何想法是怎么回事?

+4

损坏的目的正是为了防止你的第二种情况正常工作。目的是隐藏外部代码的属性。 – millimoose

回答

10

名称重整后你分配你的财产class声明的评估过程中发生。在Bar的情况下,__cache属性未被定义为类的一部分,而是在事实之后添加到特定对象。我不知道,但是无论如何,你的__cache被明确地添加到一个单独的对象中,而不是被类代码添加的)

+4

编译过程中发生了破坏。你可以使用'dis.dis()'函数来查看这个,只需运行'import dis; dis.dis(Foo .__ init __)'看看这个名字已经被修改了。 –

+0

非常有帮助,thx为解释 – gnr

7

docs

私人名称重整:当该文本上发生在 类定义的标识符与两个或更多下划线字符和 开始在两个或多个下划线并没有结束,则考虑一个私人的 该班的名字。在为其生成代码之前,专用名称将转换为更长的形式 。该转换将名称前面的 类名插入,删除了前导下划线,并且在类名前插入了一个下划线。例如, 标识符__spam发生在名为Ham的类中将为 转换为_Ham__spam。这种转换独立于使用标识符的语法上下文 。如果 转换后的名称非常长(超过255个字符),则可能会发生 实现定义的截断。如果类名 只包含下划线,则不进行转换。

类已经被定义

+0

链接到文档已损坏 –