Python双下划线修改

gnr*_*gnr 6 python attributes double-underscore private-methods python-3.x

我对这种行为感到有点困惑(使用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}
Run Code Online (Sandbox Code Playgroud)

我已经阅读了一些关于双下划线如何导致属性名称被"损坏"的内容,但在上述两种情况下我都希望使用相同的名称.

在对象名称之前单引号和双下划线的含义是什么?

有什么想法在这里发生了什么?

che*_*ner 10

在评估class语句期间发生名称重整.在这种情况下Bar,__cache属性未定义为类的一部分,而是在事后添加到特定对象.

(实际上,这可能不完全正确.在__new__方法的评估过程中可能会出现名称错误;我不知道.但无论如何,您将__cache被明确地添加到单个对象中,而不是由类代码添加.)

  • 在编译期间它被破坏了.您可以使用`dis.dis()`函数来查看这个,只需运行`import dis; dis.dis(Foo .__ init __)`看到该名称已经被破坏了. (5认同)

dm0*_*514 7

来自文档

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

在定义类之后,您将分配属性