Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python inheritance returns attribute error

Just starting out Python, i'm a fan of Derek Banas and have been following a tutorial and I'm stuck with a bit of code.

class Dog(Animal):
    __owner = ""

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

    def set_owner(self, owner):
        self.__owner = owner

    def get_owner(self):
        return self.__owner

    def get_type(self):
        print("Dog")

    def tostring(self):
        return "{} is {} cm tall and {} kilograms and say {} His owner is {}".format(self.__name,
                                                                                     self.__height,
                                                                                     self.__weight,
                                                                                     self.__sound,
                                                                                     self.__owner)

    def multiple_sounds(self, how_many=None):
        if how_many is None:
            print(self.get_sound())
        else:
            print(self.get_sound() * how_many)

spot = Dog("Spot", 53, 27, "Ruff", "Seb")

print(spot.tostring())

And i'm receiving the following error:

Traceback (most recent call last):
  File "G:/JetBrains/PyCharm Community Edition 4.5.4/PyCharm Projects/Testing 123/testing objects.py", line 87, in <module>
    print(spot.tostring())
  File "G:/JetBrains/PyCharm Community Edition 4.5.4/PyCharm Projects/Testing 123/testing objects.py", line 73, in tostring
    return "{} is {} cm tall and {} kilograms and say {} His owner is {}".format(self.__name,
AttributeError: 'Dog' object has no attribute '_Dog__name'

As I've previously transferred from programming with vb, the indentation for the format of the 'tostring' method baffles me a little bit. I even tried putting it all into one line and it still doesn't recognize the inherited attribute '__name' from the class Animal.

Help would be appreciated.

Edit:

It might be worth mentioning that i'm using Pycharm to write all this in.

Also here's the Animal class

class Animal:
    __name = ""
    __height = 0
    __weight = 0
    __sound = 0

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

    def set_name(self, name):
        self.__name = name

    def set_height(self, height):
        self.__height = height

    def set_weight(self, weight):
        self.__weight = weight

    def set_sound(self, sound):
        self.__sound = sound

    def get_name(self):
        return self.__name

    def get_height(self):
        return self.__height

    def get_weight(self):
        return self.__weight

    def get_sound(self):
        return self.__sound

    def get_type(self):
        print("Animal")

    def tostring(self):
        return "{} is {} cm tall and {} kilograms and say {}".format(self.__name,
                                                                     self.__height,
                                                                     self.__weight,
                                                                     self.__sound)
like image 277
Fluffy Sebbert Avatar asked Oct 14 '15 16:10

Fluffy Sebbert


2 Answers

Your Animal class is using Name Mangling. From documentation -

Since there is a valid use-case for class-private members (namely to avoid name clashes of names with names defined by subclasses), there is limited support for such a mechanism, called name mangling. Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped.

(Emphasis mine)

Hence , after your Animal class got defined any name such as __name would have changed to _Animal__name , etc. You would also need to access them alike that in your Dog class.

But I don't think you actually need to use Name Mangling , you should avoid using the two leading underscores, if you didn't mean for Name Mangling to happen.

like image 52
Anand S Kumar Avatar answered Nov 09 '22 23:11

Anand S Kumar


Change your function code

from

def toString(self):
        return "{} is {} cm tall and {} kilograms and say {} and the owner is {}".format(
        self.__name,
        self.__height,
        self.__weight,
        self.__sound,
        self.__owner)

to

def toString(self):
        return "{} is {} cm tall and {} kilograms and say {} and the owner is {}".format(
        self.get_name(),
        self.get_height(),
        self.get_weight(),
        self.get_sound(),
        self.get_owner())
like image 24
Simon Neubauer Avatar answered Nov 10 '22 01:11

Simon Neubauer