An introductory use of super()

In class inheritance, if a method is redefined, it overrides the parent’s method of the same name. But sometimes, we want to implement the parent’s function as well. In this case, we need to call the parent’s method.

class Animal(object): def __init__(self, name): self.name = name def greet(self): print 'Hello, I am %s.' % self.name class Dog(Animal): def greet(self): Super (Dog, self).greet() # Python3 Use super().greet() print 'WangWang... 'Copy the code

Animal (greet) Animal (greet) Animal (greet) Animal (greet) Animal (greet) Animal (greet) Animal (greet)

>>> dog = Dog('dog')
>>> dog.greet()
Hello, I am dog.
WangWang..Copy the code

One of the most common uses of super is to call the parent class’s initialization method in a subclass, such as:

class Base(object): def __init__(self, a, b): self.a = a self.b = b class A(Base): def __init__(self, a, b, c): Super (A, self) __init__ (A, b) # Python3 can use super () __init__ (A, b) the self. C = cCopy the code

In-depth super ()

Looking at the use above, you might think that using super is simple, just taking the parent class and calling its methods. In fact, in the above case, the super class happens to be the parent class, but in other cases it is not necessarily the case, super actually has no substantial relationship with the parent class.

Let’s look at a slightly more complex example involving multiple inheritance, with the following code:

class Base(object):
    def __init__(self):
        print "enter Base"
        print "leave Base"
 
class A(Base):
    def __init__(self):
        print "enter A"
        super(A, self).__init__()
        print "leave A"
 
class B(Base):
    def __init__(self):
        print "enter B"
        super(B, self).__init__()
        print "leave B"
 
class C(A, B):
    def __init__(self):
        print "enter C"
        super(C, self).__init__()
        print "leave C"Copy the code

Where, Base is the parent class, A and B inherit from Base, and C inherit from A and B. Their inheritance relationship is as follows:

      Base
      /  \
     /    \
    A      B
     \    /
      \  /
       CCopy the code

Now, let’s look at use:

>>> c = C()
enter C
enter A
enter B
enter Base
leave Base
leave B
leave A
leave CCopy the code

If you think super stands for “call method of parent class,” you’re probably wondering why the next line for Enter A is not Enter Base but Enter B. The reason for this is that super has no real connection to the parent class, so now let’s figure out how super works.

MRO list

In fact, for each class you define, Python calculates a Method Resolution Order (MRO) list, which represents the Order in which classes are inherited. We can get the MRO list for a class as follows:

>>> C.mro()   # or C.__mro__ or C().__class__.mro()
[__main__.C, __main__.A, __main__.B, __main__.Base, object]Copy the code

The MRO list of a class is the MRO list of all its parent classes. The MRO list of a class is the MRO list of all its parent classes.

  • The subclass always precedes the parent class
  • If there are more than one parent class, it is checked based on the order in which they are in the list
  • If there are two legal choices for the next class, select the first parent class

Super principle

Super works as follows:

def super(cls, inst):
    mro = inst.__class__.mro()
    return mro[mro.index(cls) + 1]Copy the code

Where CLS stands for class and INST stands for instance, the above code does two things:

  • Gets the list of MROs for inST
  • Find the index of the CLS in the current MRO list and return its next class, MRO [index + 1]

When you use super(CLS, INST), Python searches the MRO list of INST for the next CLS class.

Now, let’s go back to the previous example.

First look at the __init__ method of class C:

super(C, self).__init__()Copy the code

Where self is an instance of current C, self.__class__.mro() results in:

[__main__.C, __main__.A, __main__.B, __main__.Base, object]Copy the code

As you can see, the next class of C is A, so it jumps to A’s __init__, which prints Enter A and executes the following line:

super(A, self).__init__()Copy the code

Notice that self here is also an instance of C, and the MRO list is the same as above. Search for the next class of A in MRO and find B, so jump to B’s __init__ and print Enter B instead of Enter Base.

The whole process is fairly straightforward, but the key is to understand how super works rather than assume that it calls the methods of the parent class.

summary

  • In fact,superThere is no material connection to the parent class.
  • super(cls, inst)This is the next class of CLS in INST’s MRO list.

This post is published BY Funhacks on Creative Commons BY-NC-ND 4.0 under Creative Commons BY-NC-ND 4.0. Non-commercial reprint please indicate the author and source. For commercial reprint, please contact the author. Flask- Flask-SQLAlchemy – Flask- Flask-SQLAlchemy

The resources

  • Invoke the parent class method – PYTHon3-Cookbook 2.0.0 document
  • Understand Python Super — Laike9m’s Blog
  • Python Super () — Naruto Whirlpool — Blogosphere
  • Python: super function | “Hom
  • Python’s super () considered super! | Deep Thoughts by Raymond Hettinger
  • Python Super () inheritance and needed arguments — Stack Overflow



2 comments