Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subclass not inheriting structure from superclass properly [duplicate]

I'm just starting out with Python, but I cannot figure out why I'm having a problem with such simple class inheritance, and despite the common use of the tutorial I've been following, I haven't seen anyone else on Stack Overflow encountering this issue. Here's the code (don't worry, nothing too complicated):

import random
import sys
import os

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 toString(self):
        return "{} is {} cm tall and {} kilograms and says {}".format(self.__name,
                                                                      self.__height,
                                                                      self.__weight,
                                                                      self.__sound)

cat = Animal ('Whiskers', 33, 10, 'meow')
print(cat.toString())

bird = Animal ('Flutie', 33, 10, 'tweet')
print(bird.toString())

class Dog(Animal):

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

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

spot = Dog ('Spot', 53, 27, "Woof")

print(spot.toString())

...And here's the output:

Whiskers is 33 cm tall and 10 kilograms and says meow
Flutie is 33 cm tall and 10 kilograms and says tweet
Traceback (most recent call last):
  File "C:/.../animal_test.py", line 72, in <module>
    print(spot.toString())
  File "C:/.../animal_test.py", line 65, in toString
    return "{} is {} cm tall and {} kilograms and says {}".format(self.__name,
AttributeError: 'Dog' object has no attribute '_Dog__name'
like image 290
Platypus Egg Avatar asked Jan 23 '26 14:01

Platypus Egg


1 Answers

The double underscores represents name mangling.

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

Literally translates to this when being interpreted:

class Animal:
    def __init__(self, name, height, weight, sound):
        self._Animal__name = name
        self._Animal__height = height
        self._Animal__weight = weight
        self._Animal__sound = sound

It doesn’t matter where it’s called, or who called the __init__, the prefix _Animal will take place because it’s physically located under the Animal class.

But when you used the attributes here, as it’s physically located under the Dog class, the got name mangled to this:

class Dog(Animal):

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

    def toString(self):
        return "{} is {} cm tall and {} kilograms and says {}".format(self._Dog__name,
                                                                      self._Dog__height,
                                                                      self._Dog__weight,
                                                                      self._Dog__sound)

Which the Dog object definitely doesn’t have an attribute named self._Dog__name, instead it has the attribute self._Animal__name.

like image 137
Taku Avatar answered Jan 26 '26 06:01

Taku



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!