Search code examples
pythonpython-3.xoopsuperclass

Calling method in superclass not giving the output I expect?


I am learning about inheritance in Python and I was experimenting with superclasses and the super() function. Here is my code:

class Person:
    def __init__(self, name, age, weight):
        self.name = name
        self.age = age
        self.weight = weight

    def describe(self):
        return f"{self.name}, {self.age}, {self.weight}"


class Engineer(Person):
    def __init__(self, name, age, weight):
        super().__init__("Bla bla", 10, 100)
        self.name = name
        self.age = age
        self.weight = weight
        self.occupation = "Engineer"

    def describe(self):
        return super().describe()

my_engineer = Engineer("Larry", 17, 120)
print(my_engineer.describe())

I have a Java background, and apparently super() works differently in Python than it does in Java. In Java, the output of code equivalent to this would be Bla bla, 17, 120, but this code is outputting Larry, 17, 120. Why is this code printing out Larry, 17, 120 rather than what I expected it to? To my understanding, I am instantiating the class Engineer and passing in "Larry", 17, and 120 to __init__, but then I pass in "Bla bla", 10, and 100 to the superclass's __init__, so the superclass should be initialized with those values. Then when I call my_engineer.describe(), it should call describe() in the superclass and use the superclass's passed in values. But apparently, this is not what is happening. Can anyone explain what is going on?


Solution

  • You're seeing the attributes being overridden. What's happening in these lines of code:

    super().__init__("Bla bla", 10, 100)
    self.name = name
    self.age = age
    self.weight = weight
    self.occupation = "Engineer"
    
    • super().__init__("Bla bla", 10, 100) calls Person's __init__ with these values i.e. self = Person("Bla bla", 10, 100). If you stopped here, you'd have instantiated a subclass of Person and not really changed anything. (Same attributes, same method.)
    • When you then specify the next four attributes, you override what what you did in the previous line. These are set directly as the attributes of the class instance.

    Essentially, that looks to Python something like:

    my_engineer = Person("Bla bla", 10, 100)
    my_engineer.name = "Larry"
    my_engineer.age = 17
    my_engineer.weight = 120
    my_engineer.occupation = "Engineer"
    

    As mentioned by @Ajax1234, it seems like you want to just get rid of those four lines altogether.