light-blue light-blue - 5 months ago 33
Python Question

inheriting private variable in python

When inheriting in python, i got following error with private variables:

AttributeError: 'dog' object has no attribute '_dog__name'

I searched a lot but didn't understand where my problem is;

class animal(object):
__name = ""
__height = ""
__weight = ""
__sound = ""

def __init__(self, name, height, weight, sound):
self.__name = name
self.__height = height
self.__weight = weight
self.__sound = sound

def toString(self):
return "{} is {} cm and {} weight and say {}.".format(self.__name, self.__height, self.__weight, self.__sound)

class dog(animal):
__owner = ""

def __init__(self, name, height, weight, sound, owner):
self.__owner = owner
super(dog, self).__init__(name, height, weight, sound)

def toString(self):
return "{} is {} cm and {} weight and say {} and belongs to {}.".format(self.__name, self.__height,
self.__weight, self.__sound,

puppy = dog('puppy', 45, 15, 'bark', 'alex')



when you create var with double underscore, its just a notation use to indicate it as private variable, python do name mangling on the variable name itself to prevent normal way access to it.

However, its still not the real private variable like C/C++. You can still access the so called python "private var" with syntax below

var = __myvar
# access with _<class name>__myvar

From PEP,

  • _single_leading_underscore : weak "internal use" indicator. E.g. from M import * does not import objects whose name starts with an underscore.
  • __double_leading_underscore : when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes _FooBar__boo

For your case, change your dog class toString method to below then it should works

def toString(self):
    return "{} is {} cm and {} weight and say {} and belongs to {}.".format(self._animal__name, self._animal__height,
                                                                                self._animal__weight, self._animal__sound,
                                                                                self.__owner) # __owner remains because its not inherit from class animal

another option is to change your animal class variable to single underscore _ if you don't really need double underscore __