Двойное подчеркивание 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