Whenever code written inside a class
uses a name that begins with two underscores but doesn't also end with two underscores the compiler replaces that name with a mangled form that includes the class name:
>>> class Foo(object):
__bar = None
def set_bar(self, v):
self.__bar = v
>>> f = Foo()
>>> f.set_bar(42)
>>> f.__dict__
{'_Foo__bar': 42}
What this means in practice is that when you create subclasses then (provided the subclass has a different name than the base class) you won't accidentally collide with the private names used in the base class.
It isn't a security mechanism as you can still get at the 'private' values using getattr
, or even just the mangled form of the name, and it isn't perfect protection as sometimes class hierarchies have both base and derived classes with the same name.