How to understand the super function in a Python class

This article has participated in the "Newcomer Creation Ceremony" activity, and started the road of Nuggets creation together

foreword

In the inheritance of Python classes, you can often see the existence of the super function. What is the main function of the super function, and how to understand and use this function? This tutorial will explain in detail, I hope you will see the end and follow the actual operation of the code.

common use

Let's take a simple example. Our parent class is Human, which has two attributes, namely name and gender; and then define a subclass Student.

class Human:

    def __init__(self, name, sex):
        self.name = name
        self.sex = sex
        print('parent')


class Student(Human):

    pass


stu_1 = Student('lisi', 'male')
print(stu_1.name)

parent
lisi
复制代码

Here Student has no constructor, so it will go to the parent class to find the constructor. At this time, we need to add a constructor to the subclass, and need three attributes of name, sex, and score. If we write it directly, it should be the following code.

class Human:

    def __init__(self, name, sex):
        self.name = name
        self.sex = sex
        print('parent')


class Student(Human):

    def __init__(self, name, sex, score):
        self.name = name
        self.sex = sex
        self.score = score
        print('child')

stu_1 = Student('lisi', 'male', 97)
print(stu_1.score)

child
97
复制代码

You will find that both the parent and child classes have the same two lines of code.

self.name = name
self.sex = sex
复制代码

This is obviously incompatible with our elegant Python, so the super function comes, let's look at the code directly.

class Human:

    def __init__(self, name, sex):
        self.name = name
        self.sex = sex
        print('parent')


class Student(Human):

    def __init__(self, name, sex, score):
        super().__init__(name, sex)
        self.score = score
        print('child')

stu_1 = Student('lisi', 'male', 97)
print(stu_1.score)

parent
child
97
复制代码

We can see from the code that the super function is often used in the constructor of the subclass to call the constructor of the parent class (superclass), and does not explicitly refer to the base class.

The reason why it is said that there is no need to explicitly refer to the base class is that the function can also be achieved by calling the method of the parent class.

class Human:

    def __init__(self, name, sex):
        self.name = name
        self.sex = sex
        print('parent')


class Student(Human):

    def __init__(self, name, sex, score):
        Human.__init__(self, name, sex)
        self.score = score
        print('child')

stu_1 = Student('lisi', 'male', 97)
print(stu_1.score)

parent
child
97
复制代码

Understanding super functions

I will let you understand the super function through the following advanced knowledge points.

First, let's summarize the syntax of the super function.

super(type[, object-or-type])

super(Student, self).__init__()  #python2写法
super().__init__()  #python3写法
复制代码
not just for constructors

Although the super function is often used in constructors, other functions of the parent class can also use the super function.

class A:
    def add(self, x):
        y = x + 1
        print(y)


class B(A):
    def add(self, x):
        super().add(x)


b = B()
b.add(2)

# 3
复制代码

The reason why it is not commonly used is that since the parent class is inherited, the subclass can directly call the method of the parent class, which is just superfluous.

class A:
    def add(self, x):
        y = x + 1
        print(y)


class B(A):
    pass


b = B()
b.add(2)

# 3
复制代码
Multiple inheritance may be different

According to the above case, we can see that the super function directly calls the constructor of the base class, but multiple inheritance is different. It calls the next class in the inheritance order, not the parent class.

class Base:
    def __init__(self):
        print("enter Base")
        print("leave Base")

class A(Base):
    def __init__(self):
        print("enter A")
        super().__init__()
        print("leave A")

class B(Base):
    def __init__(self):
        print("enter B")
        super().__init__()
        print("leave B")

class C(A, B):
    def __init__(self):
        print("enter C")
        super().__init__()
        print("leave C")

C()

enter C
enter A
enter B
enter Base
leave Base
leave B
leave A
leave C
复制代码

The inheritance relationship is C-A-B-Base, so the program will go to A first, then to B, and finally to Base.

The difference between super function and calling the parent class method directly

In the case of single inheritance, we see that super and calling the parent class method directly get the same result, except that the base class is not explicitly referenced. But multiple inheritance is not needed. I modified the above code, I believe you can understand the difference.

class Base:
    def __init__(self):
        print("enter Base")
        print("leave Base")

class A(Base):
    def __init__(self):
        print("enter A")
        Base.__init__(self)
        print("leave A")

class B(Base):
    def __init__(self):
        print("enter B")
        Base.__init__(self)
        print("leave B")

class C(A, B):
    def __init__(self):
        print("enter C")
        A.__init__(self)
        B.__init__(self)
        print("leave C")

C()

enter C
enter A
enter Base
leave Base
leave A
enter B
enter Base
leave Base
leave B
leave C
复制代码

Finally, due to my limited time and ability, if there are any mistakes, please criticize and correct me, see you in the next issue~

Guess you like

Origin juejin.im/post/7079361037966770206