When do I need to use super()?

Hi, I have a question about the end of the polymorphism section (Review). I don’t understand why we have to call super() to apply append() method on our object SortedList but we don’t have to do it when we apply sort() method in the next line:

class SortedList(list):

  def append(self, value): 
    super().append(value) 
    self.sort()

Is it because we apply super().append(value) before and SortedList already behaves like a list?

Thanks for helping me!

In this case it doesn’t change much because we have not overwritten sort() in any way, so calling self.sort() will simply use the default sort() which we inherited from the list class, so using super() or not wouldn’t matter.

However, if we had modified sort(), then there could be a significant difference between calling self.sort(), that is, calling the sort() from our LinkedList class, and calling the original sort() from the list class.

9 Likes

Thank you so much for your explanation, I didn’t think about the fact we were overwriting the append() method but not sort(), I understand now :slight_smile:

1 Like

For the record, overridden is not synonymous with overwritten. We are not overwriting a parent method, but overriding it.

11 Likes

What is the difference between the two in Python?

I dont’ know that Python has a term, overwrite which means simply to replace some text with some other text. Override on the other hand means ‘to prevail over’ or ‘supersede’. The parent class method is ‘set aside’ in favor of the derived class method.

10 Likes

But aren’t we replacing text with some other text given that we’re modifying the behavior of a method when we’re overriding it? I mean, we’re literally rewriting the method, so I don’t know, seems pretty similar in this context.
But thanks for the correction, if that’s simply the terminology used I guess it’s more useful to use it, I hope it’ll stick into my memory.

1 Like

No, the overriding method is not replacement text, but the same of similar text by the same variable name in another class. It’s the existence of that other method in the subclass that permits it to override the parent.

For our own sake, we should firm up what terminology to use in any situation. It’s hard enough to learn the language, as it is. We don’t want to muddle ourselves into a bent way of thinking.

5 Likes

Quick question about the append() method. With the line: super().append(value) how does the code know which list to append the value to? For example when using append() normally, the syntax would be: listName.append(value). But here, super() is not the name of our list we want to append to. Basically my question is how come we don’t have to write something like: self.list.super().append(value) ?
I hope this question makes sense, thanks for your help.

3 Likes

Your interpretation is pretty close, but remember that self is itself a list. super() takes self along with it, saying something like, “grab this method from the parent class and run it on self.”

9 Likes

Ah i see, so the self is implied when you use super()? But isn’t self in this case our new class SortedList, not exactly a python list. So how does it know how to run append() on a new class we created? Is it because the only parameter of the class is a python list? would it not have worked if we had multiple different parameters with different types? Thanks for the response!

calling super without arguments is a bit magical (doesn’t follow normal behaviour, where does it get self from, where does it get the current class from? Magic.)
It’s obvious what’s meant, but actually typing it is a real head-scratcher.

What you get back when calling super is some kind of proxy which refers to the object in question (self), but attribute lookup skips the current class when resolving the attribute, as if it did not exist in the current class

I imagine it skips any child classes too. Search upwards, being the idea.

5 Likes

self is an object that is a single instance of the class SortedList(); its type is <class SortedList> .

Ah! I think so; it certainly seems that the SortedList object appears to the parent to be a conventional list, for which append() is a valid method.


According to the docs, super() can take as optional parameters (1) the type of the object being passed, and (2) the object itself. Thus,

super().append(value) is equivalent to super(SortedList, self).append(value)
(You can try it out in the exercise - it works!) This, I think, grounds the “magic” to which @ionatan referred.

Also from the docs: super()

… is useful for accessing inherited methods that have been overridden in a class.

Which is exactly what we are doing here with respect to append(). (You can use either self.sort() or super().sort(), since our method is not overriding the conventional obj.sort() method.)

7 Likes

Yeah the magical part is that the arguments can be left out. Python gives it special language-level treatment. Or maybe it’s just through inspection of things “under the hood” that are still visible in python. Either is magical behaviour though.

3 Likes

From what I understand it appears that “overwriting” would change the behavior/original definition of the method in the parent as well as the child, while “overriding” means the behavior of the method in the parent remains unchanged even though the child is using a modified version of the method and “overriding” the original method from the parent.

then if it is because we did not modify sort() and then it is using the default behaviour of sort() from the List class, then what is the need of calling supper() on append(). it should have used the append() just like it used sort(). And if one should say that the SortedList class tried modifying the behaviour of append(), I do not see how it was modified. it just called it to do its thing on the value.
please help me throw more light on this cos I am really confused. Thanks a lot.

Hello family, please I am lost again with this code:

`
class SortedList(list):

def init(self, lst):
self.lst = lst
super().init(lst)
self.sort()

def append(self, value):
super().append(value)
self.sort()

def str(self, lst):
return 'why all these complications with classes. {} '.format(self.lst)

x = SortedList([4, 1, 5])

print(x)

`

please tell me what is wrong with these code. First of all, I defined a str function in the SortedList class, hoping to print something. BY “format(self.lst)”, I was hoping to print the sorted list of any instance of the SortedList class.

secondly, I didn’t get the whole gist of the “super()” stuff and the dunder methods that we can build ourselves… because in it, we still use python built in object . by defining a dunder method ourselves, for example anxiety(), are we trying to overide a similar python built-in method or totally creating something that will behave like that particular built in method?
please help me explain these with maybe one good example to illustrate. thanks.

Hi, I would appreciate some explanaition on the following:

Why is self in self.sort() referring to a list? I can’t wrap my head around this.

My (flawed) thought process tells me that, because there is no constructor method in SortedList, self has to refer to the instance of Class list (the same is true for the value argument I guess).

But can that instance be a list? (sorry, you see how confused I am ;-))

Also, in the example below , I created an entry_list and a sorted_list but don’t get a correct sorted list when I am printing sorted_list.

How would I get a correct print-out of sorted list?

Thanks for your feedback, much appreciated!

class SortedList(list):
  def append(self, value):
    super().append(value)
    self.sort()
      
entry_list = list([4, 2, 3])
sorted_list = SortedList(entry_list)
print(sorted_list)

Can anyone help with this? :point_up_2:
Thanks!

self refers to the object of SortedList which has a parameter “list”. So that’s y self.sort()is still a list

1 Like