The double underscore attributes in Python has a special effect, it does "name mangling" that is it converts the attribute __var
to _A__var
i.e. _<classname>__<attributename>
at runtime.
In your example when you assign 10
to the attribute __var
of a
object, it is essentially creating a new attribute __var
and not modifying the self.__var
. This is because the self.__var
is now _A__var
due to name mangling.
This can be seen if you print the __dict__
of the a
object:
class A:
def __init__(self):
self.__var = 123
def getV(self):
return self.__var
a = A()
print (a.__dict__)
>> {'_A__var': 123}
If you don't assign any value to __var
and try to print it directly, it will result in an AttributeError
:
class A:
def __init__(self):
self.__var = 123
def getV(self):
return self.__var
a = A()
print (a.__var)
>> AttributeError: 'A' object has no attribute '__var'
Now if you try to assign to the new mangled attribute name, you would get the right result (but this process is meant to prevent accidental usage of such variables):
class A:
def __init__(self):
self.__var = 123
def getV(self):
return self.__var
a = A()
a._A__var = 10
print (a.getV())
>> 10