Python双下划线损坏

Python双下划线损坏,python,attributes,python-3.x,private-methods,double-underscore,Python,Attributes,Python 3.x,Private Methods,Double Underscore,我对这种行为感到有点困惑(使用python 3.2): 我已经读过一些关于双下划线如何导致属性名称“损坏”的内容,但我希望在上述两种情况下都会出现相同的名称损坏 你知道这是怎么回事吗?来自 私有名称损坏:当一个标识符以文本形式出现在 类定义以两个或多个下划线字符和 不以两个或多个下划线结尾,它被认为是私有的 那个班级的名字。私有名称被转换为更长的形式 在为它们生成代码之前。转换将插入 名称前面的类名,删除前导下划线,以及 在类名前面插入一个下划线。例如 出现在名为Ham的类中的标识符\uu s

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

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

你知道这是怎么回事吗?

来自

私有名称损坏:当一个标识符以文本形式出现在 类定义以两个或多个下划线字符和 不以两个或多个下划线结尾,它被认为是私有的 那个班级的名字。私有名称被转换为更长的形式 在为它们生成代码之前。转换将插入 名称前面的类名,删除前导下划线,以及 在类名前面插入一个下划线。例如 出现在名为Ham的类中的标识符
\uu spam
将 已转换为
\u Ham\u spam
。此转换独立于 使用标识符的语法上下文。如果 转换后的名称非常长(超过255个字符), 可能发生实现定义的截断。如果类名 只包含下划线,不进行任何转换


您是在定义类之后指定属性的

在计算
语句期间发生名称损坏。在
的情况下,
\uu cache
属性不被定义为类的一部分,而是在事实发生后添加到特定对象


(事实上,这可能并不完全正确。名称损坏可能发生在
\uuuuu new\uuuuu
方法的评估过程中;我不知道。但无论如何,您的
\uuuu缓存
是显式添加到单个对象中的,而不是由类代码添加的。)

损坏的目的正是为了防止第二种情况正常工作。其目的是对外部代码隐藏属性。它在编译过程中会被破坏。您可以使用
dis.dis()
函数查看这一点,只需运行
import dis;dis.dis(Foo.\uuuu init\uuuu)
查看名称是否已损坏。
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}