1

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,
                                                                                self.__owner)

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

puppy.toString()
light-blue
  • 254
  • 3
  • 12

1 Answers1

2

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 __

Skycc
  • 3,496
  • 1
  • 12
  • 18
  • tnx, is it the same for python 3 and 2? – light-blue Nov 24 '16 at 04:37
  • 1
    I think so, it should be same for python 2 and 3 – Skycc Nov 24 '16 at 04:40
  • cuz in this video, the instructor runs exactly the same code without any error; https://youtu.be/N4mEzFDjqtA?t=39m44s – light-blue Nov 24 '16 at 04:43
  • 1
    i have tested with my python3.2, it behave the same with python2, python 3 documentation `https://docs.python.org/3/tutorial/classes.html` shows the same for name mangling, no idea why it works from the video – Skycc Nov 24 '16 at 05:27