3

Why doesn't this work?

class Parent:
    __var = "Whatever"

class Child(Parent):
    def printVar(self):
        print(self.__var)


Timmy = Child()

Timmy.printVar()

I get the following exception:

Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<stdin>", line 3, in printVar
AttributeError: 'Child' object has no attribute '_Child__var'
julienc
  • 19,087
  • 17
  • 82
  • 82
  • It's often a good idea to start variable names of instances with lowercase so they're not confused with a class. So *Timmy* should be replaced by *timmy* – Ted Klein Bergman Jul 13 '16 at 17:40

3 Answers3

2

This is because you chose to name the attribute with a double leading underscore. This triggers some name-mangling

You can access it as self._Parent__var

In [8]: class Parent:
    __var = "Whatever"
   ...:     
In [9]: class Child(Parent):
    def foo(self): print self._Parent__var
   ...:     
In [10]: a=Child()
In [11]: a.foo()
Whatever

More information is available in the python docs at https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references

kdopen
  • 8,032
  • 7
  • 44
  • 52
1

You have provided __var as a class variable which is name-mangled due to the double-leading underscore. Hence, you cannot access it nicely with __var, but rather would need to use self._Parent__var. It can only be accessed by instances of Parent with __var, and not any sub-classes.

Hence, to still indicate that the attribute is private but avoid this name mangling, you may consider just using a single underscore.

class Parent:
    _var = "Whatever"

class Child(Parent):
    def printVar(self):
        print(self._var)
miradulo
  • 28,857
  • 6
  • 80
  • 93
  • Can someone explain under what circumstances (and why) one would use the the double underscore rather than the single underscore? – Thomas Fernandez Jul 15 '16 at 02:09
  • @ThomasFernandez You may want to take a look at [this question](http://stackoverflow.com/questions/1301346/the-meaning-of-a-single-and-a-double-underscore-before-an-object-name-in-python). Effectively it is a matter of convention and your use case, and whether you want the name-mangling to occur. – miradulo Jul 15 '16 at 04:14
  • just use a property decorator – dev Sep 09 '22 at 23:28
0

Double underscore is used for private attributes, you should use single underscore.

class Parent:
    _var = "Whatever"

class Child(Parent):
    def printVar(self):
        print(self._var)


Timmy = Child()

Timmy.printVar()