Двойное подчеркивание Python

Я немного сбит с толку этим поведением (используя 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}

Я немного прочитал о том, как двойные подчеркивания приводят к искажению имен атрибутов, но я ожидал одинакового искажения имен в обоих случаях выше.

Что означает одинарный или двойной знак подчеркивания перед именем объекта?

Есть идеи, что здесь происходит?

2 ответа

Решение

Искажение имени происходит во время оценки class заявление. В случае Bar, __cache Атрибут не определяется как часть класса, а добавляется к конкретному объекту после факта.

(На самом деле, это может быть не совсем правильно. Во время оценки __new__ Способ; Я не знаю. Но независимо от вашего __cache добавляется явно к одному объекту, а не коду класса.)

Из документов

Private name mangling: When an identifier that textually occurs in a class definition begins with two or more underscore characters and does not end in two or more underscores, it is considered a private name of that class. Частные имена преобразуются в более длинную форму, прежде чем для них генерируется код. Преобразование вставляет имя класса перед именем, с удаленными начальными подчеркиваниями и одним подчеркиванием, вставленным перед именем класса. Например, идентификатор __spam occurring in a class named Ham will be transformed to _Ham__spam, Это преобразование не зависит от синтаксического контекста, в котором используется идентификатор. If the transformed name is extremely long (longer than 255 characters), implementation defined truncation may happen. If the class name consists only of underscores, no transformation is done.

You are assigning your property after the class has been defined

Другие вопросы по тегам