0

Consider a scenario where there is a child class and a single parent class, ParentClass. The goal is to override a method named my_method from the parent class in the child class. I have seen two ways of calling the my_method in the parent class when defining a similarly named method in the child class:

  1. super().my_method(args)
  2. ParentClass.my_method(self, args)

Which method is more common? Which one do you find clearer?

I have a feeling No. 1 is more common but I personally find No. 2 clearer. Because it makes the presence of self explicit. It is worth noting that we drop the self argument when calling an instance method on an instance of a class. Dropping the self argument here may lead to confusion between these two cases. Therefore, in my opinion, No.2 should be preferred over No. 1.

I wonder what others think about the popularity and appropriateness of these two methods.

Note. A common example of my_method is the __init__ method.

H D
  • 151
  • 6
  • 1
    One argument for #1 is the DRY principle. If I have a class `Child(Parent)` and I want to make it instead inherit from `OtherParent`, then with approach #1 I only need to change the class definition to `class Child(OtherParent)`. In approach #2 I need to find all the calls to parent methods and change them. – slothrop Jul 19 '23 at 19:32
  • 1
    Does this answer your question? [Super init vs. parent.\_\_init\_\_](https://stackoverflow.com/questions/29173299/super-init-vs-parent-init) – mkrieger1 Jul 19 '23 at 19:37
  • 2
    `super()` is more compatible with cooperative multiple inheritance. See [this video](https://www.youtube.com/watch?v=X1PQ7zzltz4) for details – Alexander Jul 19 '23 at 19:51
  • @slothrop Thank you! That makes sense! I am thinking the expression `super().my_method(self, args)` would have the benefits of both worlds. Any idea why people haven't used this expression? The closest I've seen is `super(ChildClass, self).my_method(args)`. But it sounds weird to me to put `self` in the first parentheses instead of the second one -- right next to `args`. – H D Jul 19 '23 at 20:07
  • 1
    I guess it's a bit subjective, but to me, it's natural and consistent to do `super().my_method(blah)`. Because if you were calling a different method in the same instance, I think you would prefer to do `self.other_method(blah)` rather than `ChildClass.other_method(self, blah)` ? – slothrop Jul 19 '23 at 20:15
  • @slothrop Thank you for the insights, but I think the two scenarios are different. As you know, when we call `instance.instance_method(args)` in Python, the instance on which the `instance_method` is called is automatically passed to the `instance_method`. In the case of `self.other_method(blah)`, `self` represents an instance of the child class. Following the rule mentioned above, `self` will be passed as an argument to `other_method`, which is desirable because we may want to add instance attributes to it inside the `other_method`. – H D Jul 19 '23 at 23:13
  • @slothrop The case of `super().my_method(blah)` is different as it may sound like we are passing an instance of the *parent class* to `my_method`, which is misleading. – H D Jul 19 '23 at 23:13
  • 1
    2. remind me python2.X _old style classes_ – cards Jul 20 '23 at 07:18
  • 1
    @HD yes, true, that's a fair point - I see your reasons for having the preference you do. – slothrop Jul 20 '23 at 07:22
  • 1
    (The "answer" is that `super()` isn't the parent class or in instance of it, it's a proxy object which is, loosely speaking, "self, but with a special MRO that skips self's own class". Hence the parallel between `super().my_method(blah)` and `self.other_method(blah)`. But you could reasonably say that it's quite difficult to get one's head around exactly what `super()` is.) https://docs.python.org/3/library/functions.html#super – slothrop Jul 20 '23 at 07:58

1 Answers1

4

The method using super() is more common due to its flexibility and the fact that it deals with complex scenarios such as multiple inheritance. It also doesn't require you to specify the parent class' name (you do not even need to know it). I'd say the versatility of super() makes it recommended approach unless you know you want otherwise.

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141