Python – Accessing private class variable

classpropertiespythonpython-2.7scope

While learning Python, I came accross this strange behavior :

Consider this simple class :

class Human(object):
  def __init__(self, name):
    self.__name = name

  def description(self):
    print("Hello, my name is %s" % self.__name)

I want to avoid being able to alter the name after the object has been created.

If I use this :

MyHuman = Human("Andy")
MyHuman.__name = "Arthur"
MyHuman.age = 23

MyHuman.description()
print MyHuman.age

It doesn't change the name after the object instanciation, which is good because I want the instance variable to be private. On the other hand, I thought it would complain about accessing this variable. It doesn't even complain about accessing a mysterious "age" variable and prints it properly later.

I come from C# and it seems odd to me. Where is my mistake ?

Best Answer

You should know the following:

  1. When you write to an attribute of an object, that does not exist, the python system will normally not complain, but just create a new attribute.
  2. Private attributes are not protected by the Python system. That is by design decision.
  3. Private attributes will be masked. The reason is, that there should be no clashes in the inheritance chain. The masking is done by some implicit renaming. Private attributes will have the real name
  "_<className>__<attributeName>"

With that name, it can be accessed from outside. When accessed from inside the class, the name will be automatically changed correctly.