Python: You don't know the super

Source: Internet
Author: User

Getting Started with super ()

In the inheritance of a class, if you redefine a method that overrides a method of the same name in the parent class, but sometimes we want to be able to implement the function of the parent class at the same time, we need to invoke the parent class's method, which can be achieved by using super, such as:

class Animal(object):    def __init__(self, name):        self.name = name    def greet(self):        print ‘Hello, I am %s.‘ % self.nameclass Dog(Animal):    def greet(self):        super(Dog, self).greet()   # Python3 可使用 super().greet()        print ‘WangWang...‘

Above, Animal is the parent class, dog is a subclass, we redefine the greet method in the dog class, in order to be able to implement the function of the parent class at the same time, we call the parent class method, see the following use:

>>> dog = Dog(‘dog‘)>>> dog.greet()Hello, I am dog.WangWang..

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

class Base(object):    def __init__(self, a, b):        self.a = a        self.b = bclass A(Base):    def __init__(self, a, b, c):        super(A, self).__init__(a, b)  # Python3 可使用 super().__init__(a, b)        self.c = c
Deep Super ()

Looking at the use above, you might think that super is very simple to use, just get the parent class and call the parent class method. In fact, in the above case, Super gets the class is just the parent class, but in other cases is not necessarily, super and the parent class does not actually have a substantial association.

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"

Where base is the parent class, A, b inherits from Base, C inherits from A, B, and their inheritance is as follows:

      Base      /       /        A      B     \    /      \  /       C

Now, let's take a look at using:

>>> c = C()enter Center Aenter Benter Baseleave Baseleave Bleave Aleave C

If you think super represents the "method of calling the parent class", you'll probably wonder why the next sentence of enter a is not enter Base but enter B. The reason is that super and the parent do not have a substantial association, so let's now get a sense of how super works.

MRO List

In fact, for each class you define, Python calculates a list of method parsing orders (methods Resolution Order, MRO) that represents the order in which classes are inherited, and we can use the following method to obtain a list of the MRO for a class:

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

So what is the order of the MRO list, which is achieved through a C3 linearization algorithm, where we don't delve into this algorithm, and interested readers can get to know for themselves, in general, a class of MRO list is to merge all the parent class MRO list, and follow the following three principles:

    • Subclasses are always in front of the parent class
    • If there are multiple parent classes, they are checked according to their order in the list
    • If there are two legitimate choices for the next class, select the first parent class

      Super principle

      The super works as follows:

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

      Where the CLS represents the class, inst represents the instance, and the code above does two things:

    • Get the MRO list for Inst
    • Finds the CLS's index in the current MRO list and returns its next class, Mro[index + 1]
      When you use Super (CLS, inst), Python searches the Inst's MRO list for the next class on the CLS.

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

First look at the init method of class C:

super(C, self).__init__()

The self here is the current instance of C, self. The class. MRO () results are:

[__main__.C, __main__.A, __main__.B, __main__.Base, object]

As you can see, the next class of C is a, so jump to the initof A and print out enter a, and execute the following line of code:

super(A, self).__init__()

Note that the self is also the current instance of C, the MRO list is the same as above, search for a in the MRO of the next class, the discovery is B, so, jumped to the B init, then print out enter B, instead of enter Base.

The whole process is still clearer, and the key is to understand how super works, rather than assuming that super calls the method of the parent class.

Summary

In fact, super and the parent class have no substantive associations.
Super (CLS, Inst) obtains the next class in CLS's MRO list in Inst.

Python: You don't know the super

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.