Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set your subtitle preferences in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please refer to our video player troubleshooting guide for assistance.

Object Inheritance in Python

While Python isn’t purely an object-oriented language, it’s flexible enough and powerful enough to allow you to build your applications using the object-oriented paradigm. One of the ways in which Python achieves this is by supporting inheritance, which it does with super().

By the end of this course, you’ll be able to:

  • Compose a class
  • Use super() to access parent methods
  • Understand single and multiple inheritance

In this lesson, you’ll cover how to use super() to access a parent class’s constructor:

Python
class Rectangle:
    def __init__(self, length, width):
        self.length = length
        self.width = width

    def area(self):
        return self.length * self.width

    def perimeter(self):
        return 2 * self.length + 2 * self.width

class Square(Rectangle):
    def __init__(self, length):
        super().__init__(length, length)
Download

Course Slides (PDF)

896.4 KB

00:00 Welcome to Inheritance and super() in Python. My name is Chris and I will be your guide. This course is split up into three lessons. The first lesson talks about inheritance and objects and classes in Python, and quickly shows you how to use the super() function to get at the parent attributes and methods in inheritance. The second and third lessons talk about single and multiple inheritance and how to use super() to get at those objects as well.

00:24 First off, a quick warning. The syntax for inheritance has changed between Python 2 and Python 3. All the examples I’ll be using in this course will be based on Python 3.

00:33 So, let’s get started. In this lesson, I’ll be talking about classes and objects, when to use them, why, and how. So, what is an object? An object is just a way of grouping data and methods together, usually for things that belong together and help you organize your code.

00:48 Frequently, an object maps to something in the real world. If you’re writing software that describes a class schedule, you might have a person object with a name and an address attribute, and methods on that for adding that person to a course or saving their data. Similarly, if you were writing accounting software, your balance sheet object might have a list of assets and a list of liabilities as the attributes, and a method for totaling the assets or taking a report. A class defines how to make an object, and is actually in Python how you create the object itself, which is called instantiation.

01:24 I’m going to start with some examples that are based on geometric shapes. If you’re coding along with me, I’m putting it inside of a file called shapes.py.

01:32 This is the simplest possible class. It’s two lines. It starts with the keyword class and the name of the class, Square. By convention in Python, you always capitalize the name of your class.

01:45 The pass keyword tells Python that there’s nothing else in this class besides an empty definition. If you open up a REPL and import the Square class from shapes, you can then instantiate it by calling it. The Square, on the right-hand side, capital S, is my class.

02:02 I call it using the parentheses (), and I end up with an object that I’ve named square. I can now add attributes to that square, maybe a .length of 3, and I can examine that square by using the built-in function called dir().

02:18 There’s a lot of content here. Don’t worry about it too much. There’s just two things I want to point out. On the bottom right-hand side, you’ll notice 'length'.

02:27 When I added the .length attribute to square, dir() shows that it’s there. In the top left, there’s a special method '__class__' that contains information about the class the object came from. If I look at that now in the REPL,

02:42 it produces a class object that says this is a Square. You can always figure out what class an object comes from by examining this property. Now I want to add some complexity to the Square.

02:56 First off, you’ll recall I added an attribute .length. Well, the Square without a .length isn’t useful, so I want to make sure that a .length is always there.

03:06 You can do this by changing the constructor. The constructor in Python is called .__init__(). This method gets called every time a class constructs an object.

03:18 The default one doesn’t take any parameters. I’ve changed this one to take a parameter called .length. I then store that on the object itself that gets created from the class.

03:29 Now it won’t be possible to create a Square without a length being defined and that attribute stored on the object. In addition to storing the .length, I’ve also defined two methods, .area() and .perimeter().

03:43 These return the area and perimeter of the Square itself, by doing math on the .length.

03:51 You can see this inside of the REPL. Importing from Square like before, now I’m passing in the length of 3 as part of the constructor. I get my .length, it returns a value 3. I can call the .area() method, I get 3 * 3 is 9. And once again, I can look at dir() to examine the object.

04:13 In addition to having the '__class__' as before, on the bottom right side now you can see 'area', 'length', and 'perimeter', the methods and attributes that were defined in the class. Great, so I’ve got my square. Now I want to add another shape. This time, it’s a Rectangle. This is going to be very similar to my Square.

04:36 Instead of needing a length on its own, I need a length and a width. Like before, I used the .__init__() method to pass in those as parameters and save them on the object.

04:47 And also like before, I have .area() and .perimeter() methods to do the calculations based on the .length and .width of the Rectangle.

04:57 Once again, import it from the REPL,

05:01 passing in a length and a width.

05:04 And I get the expected result.

05:08 The two classes I’ve defined so far, the Square and the Rectangle, are very, very similar. This is a problem. If it turns out there was a bug in the .area() method of one, because I duplicated it in the other, I probably have to fix it in two places.

05:21 One of the ways of simplifying this is by using inheritance. Instead of defining the Square and the Rectangle separately, I’m going to define the Square based on the Rectangle, replacing the code you see here with the new code at the bottom.

05:35 In this case, Square, having Rectangle in brackets, inherits from the Rectangle object. I don’t have to define anything new on it.

05:45 It will inherit anything that I don’t override from the Rectangle. The .__init__() method does need to be overridden. The Rectangle takes a length and a width. The Square only takes a length, so I need to redefine this method. This is where super() comes in.

06:01 super() allows me to access the parent’s methods—in this case, the parent Rectangle.__init__() method—and I’m going to pass in a length for the Rectangle length and width.

06:13 I don’t have to specify anything else. The .area() and .perimeter() will now come from the Rectangle class from before.

06:22 Inside of shapes.py, I’ve replaced the old Square definition with this new inherited code. Like before, I can use the REPL and import the Square, instantiate it with a length of 3. If I look at the .__class__, not surprisingly, it’s a Square. If I look at the dir() of the object, you’ll see a few new things. For starters, at the bottom, the 'width', 'perimeter', 'length', and 'area' are all there.

06:49 The .area(), .perimeter(), and .width are inherited from the Rectangle class. The .length is passed in, in the constructor.

06:57 I can also look at the .__bases__ attribute of the .__class__ attribute. This can tell you where your inheritance is from. Because Square inherits from Rectangle, the .__bases__ value shows the Rectangle class. In the next lesson, I’m going to show you how to use super() to look at different methods and attributes inside of single inheritance.

Many thanks for the interesting course! May i ask what text editor did you use? :)

swapniltambe93 on May 4, 2020

Hi Christopher, thanks for this amazing video lecture. I just have one query which as follows, why are you using lenght twice here in class Square(Rectangle): def init(self, length): super().init(length, length)

Roy Telles on Aug. 11, 2020

I think the reason for passing length twice in super().__init__(length, length) is because a Square’s width is essentially its length. And since a Square is a Rectangle, we need to pass its length again to the Rectangle’s width parameter.

Christopher Trudeau RP Team on Aug. 12, 2020

Yes Roy, you’re right! The Rectangle class takes two parms its width and its length. The Square inherits from Rectangle and needs to pass in those same to parms. In the case of the Square the length and width are the same thing, so it gets passed in twice.

Christopher Trudeau RP Team on Aug. 12, 2020

I know this answer is very late, but in case anyone else is curious, I don’t use a text editor to do these demos. I find it hard to type and talk at the same time, so I wrote a custom utility that makes it look like I’m doing that. The tool uses Urwid, a curses-like command line GUI thing and Pygments for the colourization.

It is available on PyPI and the code is here:

github.com/cltrudeau/purdy

(the pedantic answer to your question is Vim though, I’m old and old-school :) )

Dan B on Nov. 13, 2020

The from shapes import Square bit was a surprise to me! Where can I learn about how to structure code in python?

Christopher Trudeau RP Team on Nov. 13, 2020

Hi Dan,

If you’re interested in packages and modules in Python, you might like the following course:

realpython.com/courses/python-modules-packages/

Happy coding!

Dan B on Nov. 13, 2020

Thanks.

Become a Member to join the conversation.