Calling the method in the parent class in Python and introducing the super() function

1. General

super() returns the temporary object of the parent class, and then you can call the method of the parent class. It is often used to extend the method of the parent class. It directly calls the method of the parent class by using the super() statement, which does not need to be re implemented in the subclass, and uses the least code to extend the method of the parent class.

An example:

Create a rectangle class, including 2 attributes of length and width, and 2 functions of perimeter and area.

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 + self.width)

  If we need a square class, we can choose to create a class

class Square:
    def __init__(self, length):
        self.length = length

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

    def perimeter(self):
        return 4 * self.length

  Since the square is a special rectangle, the two classes in the code are irrelevant. By using inheritance to create classes, we can logically reflect the relationship between squares and rectangles, and reduce the amount of code.

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

  super()   Returns a parent class of the current object, so we call the Rectangle of the parent class in the code. init__ Method to create a rectangle of equal length and width.

  2. Function of super ()

Here's what super() does

super(SubClass, instance)    Two parameters: the first parameter is a subclass, and the second parameter is the object as an instance of the subclass

In Python 3, for convenience, some simplifications have been made. super() used in Square class is equivalent to super(Square, self)   The first parameter refers to the subclass Square, and the second parameter refers to a Square object, self.

Let's create a cube class

class Cube(Square):
    def volume(self):
        face_area = super(Square, self).area()
        return face_area * self.length

In the Cube class, the first parameter to use the super() function is the Square class, which results in the search for the area() method from the parent class of Square. The second parameter, self, is an instance, which provides the context of the object for the method of the parent class, such as the instance attribute length required by the area function in this example.

  3. super() in multiple inheritance

In addition to single inheritance, Python also supports multiple inheritance. A subclass can inherit from multiple parent classes. Continuing with the previous example, we

Create two more classes, Triangle and Pyramid  

class Triangle:
    def __init__(self, base, height):
        self.base = base
        self.height = height

    def area(self):
        return 0.5 * self.base * self.height

class Pyramid(Triangle, Square):
    def __init__(self, base, slant_height):
        self.length = base
        # The distance from the bottom of a plane triangle to the top of a pyramid
        self.slant_height = slant_height

    def area(self):
        bottom_area = super().area()
        plane_area = 0.5 * self.length * self.slant_height * 4
        return bottom_area + plane_area

  I want to ask the surface area of the Pyramid = bottom (square area) + side (triangular area) * 4. Since Pyramid inherits from two parent classes (area methods are defined for triangles and squares), which parent class method is called when super().area() is called.

3.1 mro (method resolution order)

Each class has a__ mro__ Property to describe its inheritance relationship. We check the following pyramid classes__ mro__ Can see

In [3]: Pyramid.__mro__
Out[3]: (__main__.Pyramid, __main__.Triangle, __main__.Square, object)

  The resolution order is pyramid > Triangle > square > object     Therefore, when we call super().area, we will first parse the area formula of the Triangle.

In [4]: pyramid = Pyramid(3,2)
In [5]: pyramid.area()
---------------------------------------------------------------------------
AttributeError: 'Pyramid' object has no attribute 'height'

You can see that the function reports an error because the height attribute is not defined in the pyramid.

3.2 solutions

① You can change the order of parent classes by modifying the order in which they are defined__ mro__ The order of. Put the Square class first

class Pyramid(Square, Triangle):
    def __init__(self, base, slant_height):
        self.length = base
        # The distance from the bottom of a plane triangle to the top of a pyramid
        self.slant_height = slant_height

    def area(self):
        bottom_area = super().area()
        plane_area = 0.5 * self.length * self.slant_height * 4
        return bottom_area + plane_area

  As you can see, the output is normal.

In [8]: pyramid = Pyramid(3,2)
In [9]: pyramid.area()
Out[9]: 21.0

  ② , a better way is to avoid the function with the same name in the parent class of the same level during multi inheritance, and rename the area function in Triangle

class Triangle:
    def __init__(self, base, height):
        self.base = base
        self.height = height

    def tri_area(self):
        return 0.5 * self.base * self.height

class Pyramid(Triangle, Square):
    def __init__(self, base, slant_height):
        self.length = base
        # The distance from the bottom of a plane triangle to the top of a pyramid
        self.slant_height = slant_height
        super().__init__(base, slant_height)

    def area(self):
        bottom_area = super().area()
        plane_area = super().tri_area() * 4
        return bottom_area + plane_area

 

 

Tags: Python

Posted on Tue, 07 Sep 2021 20:57:44 -0400 by harishkumar09