Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language 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 see our video player troubleshooting guide to resolve the issue.

super() and the Inheritance Hierarchy

Give Feedback

In the previous lesson, you covered objects and inheritance. In this lesson, you’ll dive deeper into method overriding and see how to use super() to access overridden parent methods:

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

    def what_am_i(self):
        return 'Rectangle'

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

    def what_am_i(self):
        return 'Square'

class Cube(Square):
    def surface_area(self):
        face_area = self.area()
        return face_area * 6

    def volume(self):
        face_area = super().area()
        return face_area * self.length

    def what_am_i(self):
        return 'Cube'

    def family_tree(self):
        return self.what_am_i() + ' child of ' + super(Cube, self).what_am_i() 

Brandon on Jan. 29, 2020

Thanks for video. One problem, though. I keep getting an AttributeError when calling cube.volume(): type object ‘super’ has no attribute ‘area’ The cube instance of Cube has the property “area”, but it’s throwing an error when it goes looking for it in the parent(s). When I replace face_area = super().area() with face_area = self.area(), cube.volume() works fine. Any thoughts?

Brandon on Jan. 29, 2020

It appears the issue may be with the import into the iPython terminal. When I run the code in the Python Interactive Window in VS Code it’s fine, but calling cube.volume() after importing via the terminal (into iPython) throws the error. Oh well, no worries. Thanks!

Mark on June 15, 2020

Hey Everyone, am sorry if this question is stupid. I am a little struggling, when i import the Parent class all is well but if i import the child class i get this area

from shapes import Rectangle, Square, Cube
>>> cu = Cube(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/real_python_project/int/shapes.py", line 15, in __init__
    super().__init__(length, length)  # accessing the parent method intialisation
TypeError: __init__() takes 2 positional arguments but 3 were given

Christopher Trudeau RP Team on June 16, 2020

Hi UgandanGuy,

I’m only guessing as I can’t see your code, but if you inherited from Rectangle instead of Square, you might see this message. Rectangle takes two arguments (which means 3 because of “self”), whereas Square only takes one (which means 2 because of “self”).

Double check you have:

class Cube(Square): . . .

…ct

Thomas J Foolery on June 23, 2020

Thanks Christopher. I liked the video. I was working along side you but not copying verbatim. My little toy looks like this:

# in shapes.py
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 (self.length + self.width) * 2

    def __str__(self):
        return "rectangle with length = {} and width = {}".format(self.length, self.width)

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

    def __str__(self):
        return "square with side-length = {}".format(self.length)


rect = Rectangle(2,4)
print("Rectangle of length {} and width {} has area {} and perimiter {}".format(rect.length, rect.width, rect.area(), rect.perimeter()))

sq = Square(6)
print("Square with sides = {} has area {} and perimeter {}".format(sq.length, sq.area(), sq.perimeter))

print(rect)
print(sq)

The output looks like this:

Rectangle of length 2 and width 4 has area 8 and perimiter 12 Square with sides = 6 has area 36 and perimeter <bound method Rectangle.perimeter of <main.Square object at 0x102e32940>> rectangle with length = 2 and width = 4 square with side-length = 6

Process finished with exit code 0

It seems the perimeter method doesn’t get inherited quite as expected. I’m using PyCharm with Python 3.6. Any thoughts?

Christopher Trudeau RP Team on June 23, 2020

Hi Thomas,

You’ve missed the function call brackets to perimeter. The output you’re seeing is Python telling you about the function rather than calling the function.

Change your line to this:

print("Square with sides = {} has area {} and perimeter {}".format(sq.length, sq.area(), sq.perimeter()))

And you should be good to go.

davevikram on June 23, 2020

Hello Chris,

I was following the tutorial and everything was fine until i created Cube class and I can’t get past this error. I even copied the code from above and still continue to get this error.

ImportError: cannot import name ‘Cube’

from shapes import Cube Traceback (most recent call last): File “<stdin>”, line 1, in <module> ImportError: cannot import name ‘Cube’

Please advise.

Thanks, dave

Become a Member to join the conversation.