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