1

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?

2
  • 2
    You immediately replace the attribute values set by the parent __init__, explicitly; why is that surprising? Commented Mar 18, 2018 at 21:59
  • 2
    "I have a Java background, and apparently super() works differently in Python than it does in Java. " You are correct. super() works differently in Python than in Java. As a note of advice, it's best not to try to project concepts learned in one language on another language you're learning. While languages do have certain broad aspects in common (inheritance, in this case), the way these concepts are implemented are often very different. When learning a new language, It's best to treat it as a separate, unique language, without importing other ideas from other languages learned. Commented Mar 18, 2018 at 22:07

2 Answers 2

4

super is working correctly; however, after the super call, you override every attribute with the values passed to the child constructor. Instead, simply call super and do not initialize the child class with the same attributes:

class Engineer(Person): def __init__(self, *args): super().__init__("Bla bla", 10, 100) def describe(self): return super().describe() my_engineer = Engineer("Larry", 17, 120) print(my_engineer.describe()) 

Output:

Bla bla, 10, 100 
Sign up to request clarification or add additional context in comments.

Comments

3

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.

4 Comments

So what I'm getting from this is that in Python, it is better to call super().__init__ at the end of the child class's __init__ rather than the beginning when you are setting the attributes of the child class (unlike Java where the standard is to put super() in the beginning)?
Eh .. not to be rude but I would say that's missing the point a bit. While a lot of people dislike the book for various reasons, Learn Python the Hard Way has a useful sections on parent/child class interaction and the 3 ways to go about it.
It's common to see super used to inherit some attributes and then also set some additional attributes that don't come along with the parent class. So in this case, you'd be indifferent between order.
Looking at your question closely, I suppose you'd want to call super() last, but I'm not exactly following what you're trying to do here. It all seems a bit redundant

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.