Introducing the super() Function
00:00 Sometimes you want to override a certain method, but maybe you just want to add a bit to the end or to the beginning. You don’t want to just override the whole thing, especially if the method is quite large.
00:12
The super()
function allows you to access the original method of the parent class while you’re still overriding it in your subclass. So to put that in a slightly different way, sometimes you need to extend a certain method, and within that method, you can call the parent class’s method with the super()
function.
00:32
This is very common to see in an .__init__()
constructor. For example, you’ll recognize most of this code from previous lessons.
00:43
You’ve got your custom exception up here. You’ve got your Point
class, which has been abbreviated here, just so it all fits on the screen. You’ve got your Shape
class, which has a space here for something that we’re going to add in in a second.
00:57
Then you’ve got your Square
class, which subclasses Shape
and adds in this check here to make sure that it has four points. But this code currently has a problem.
01:09
You accept a list of points as the attribute that goes to self.points
—same here—and you’re checking if the length is 4
. There should be four points for a square. That makes sense.
01:22 But someone could pass in a list of numbers or strings, and as long as there are four of them, that would still work. So you really want to add in a check here to make sure each of them are points.
01:33
You might do this by saying for point in points:
if not isinstance(point, Point)
, then you can raise a TypeError
. We’re not subclassing this because the TypeError
is quite a common type of error.
01:47
You often pass in the wrong type to a function, and in this case, that’s what’s happening here. If all the points are not instances of the Point
class, then they should raise a TypeError
.
02:00 But now, the way you’ve currently got it set up, you’d have to copy this check into here before or after.
02:10
That’s not ideal because then we’re just copying code, which is one of the big reasons we learn how to code is to not repeat ourselves. So what you can do is use the super()
function.
02:21 You’ll see that this line here has now changed.
02:25
Instead of self.points = points
, you’re calling super().__init__(points)
. What’s happening here? super()
is like a reference to the parent, and then it’s saying, okay, get the parent, and then get the .__init__()
method from the parent here, and then we’ll pass in the points to that function.
02:53 Basically, this is like just adding this check before this check.
03:00
You could put the super()
beforehand. That would also work. But it makes sense to have it after because we want to make sure that we’ve gone through all the checks before we assign the points to the instance as an attribute, namely that the code has checked whether the number of points is 4
and then whether all the points are actually instances of the Point
class, and finally assign the points to the instance.
03:26
Let’s look at that in action. With this code loaded up, you can see that the Square
shape has the super()
call in it, but if we were to revert this and put this back into self.points
, so it’s not using the super()
function, this is no longer paying attention to the check to make sure all the points are actually instances of the Point
class.
03:52
You can verify this by maybe creating an instance of Square
, and instead of passing four points, we’ll just pass in four ones, four integers.
04:02 There are four of them, but they’re not points. So this shouldn’t really be a valid shape. Control + S to save it, and then F5 to run it.
04:11
You’ll see that it creates without any errors, and if you look at box
, you’ll see that it’s a Square
object, but if you look at the points, then you’ll see that this is just a list of numbers, not of points.
04:24
So we really want to catch this. The naive way might be to just copy and paste all of this into here. Now this won’t run. If I press Control + S and then F5 to run it, I’ll get an error. It’s saying all points should be members of the Point
class, so that works. But we’re duplicating code here, and we don’t need to.
04:44
What we can do instead is add our check and then call this constructor method as if it was part of this method. And the way you can do that is with the super()
function.
04:59
So super()
, that grabs the original class, then we reference the .__init__()
constructor method, then we pass in the arguments that would be passed into that.
05:12
So we can pass in the points. So we’re getting the points that were originally passed in, we’re checking to make sure there are four, and then we’re passing it to the original constructor here, and then that becomes the points
here.
05:25
Then self.points
gets assigned to the instance as if it were in here.
05:32
So now if we save and run, you’ll see that we get the TypeError
still, even though we don’t have it in this function. So the way to fix this would be to replace all of these with points.
05:56
Say (0, 0)
… do a bit of copy/pasting …
06:03
make that (0, 1)
, (1, 1)
, (1, 0)
. Okay, so now we Control + S to save that and then F5 to run it, and we’re not getting any errors. And if we look at our box
, we’ll see that it’s a Square
object, and if we look at our points within that box, we can see that we have four Point
objects in there.
06:26
So that’s the super()
function. It doesn’t work just for the constructor. You can call any method that is on the parent class with the super()
function.
06:37
The super()
function can be quite confusing, so don’t worry if you don’t get it all just yet. There’s plenty more material to go through if you want to know more about super()
.
Become a Member to join the conversation.