Python double underscore mangling

I am a little confused by this behavior (using 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} 

I got a little familiar with how double underscores cause attribute names to be β€œgarbled”, but I expected that in both cases the above would be named.

What is the meaning of a single and double underscore in front of an object name?

Any ideas what is going on here?

+6
source share
2 answers

In the process of evaluating the class operator, a name change occurs. In the case of Bar the __cache attribute __cache not defined as part of the class, but rather is added to the specific object after the fact.

(Actually, this may not be entirely correct. When evaluating the __new__ method, a __new__ may occur. I don’t know. But independently, your __cache added explicitly to one object, not added class code.)

+10
source

From docs

Private name: when an identifier that has a textual value in a class definition begins with two or more underscores and does not end with two or more underscores, the name of this class is considered private. Private names are converted to a longer form before creating code for them. The conversion inserts the class name before the name, removing leading underscores and one underscore is inserted before the class name. For example, the __spam identifier that occurs in a class named Ham will be converted to _Ham__spam . This conversion is independent of the syntactical context in which the identifier is used. If the converted name is extremely long (longer than 255 characters), a specific truncation can be implemented. If the class name consists only of underscores, the conversion is not performed.

You assign your property after class definition

+7
source

All Articles