Super in Python

Source: Internet
Author: User

Go to: https://mozillazg.com/2016/12/python-super-is-not-as-simple-as-you-thought.html

When it comes to super, you may find it simple, not just to call the parent method. If it is so simple, then there will not be this article, and listen to me carefully.

Conventions

Before you begin, let's make an appointment with the Python version that this article uses. The default is Python 3, which means that the classes defined in this article are new classes. If you use Python 2, remember to inherit object:

1 # by default, Python 3 2 class A: 3     Pass 4 5 # Python 2 6 class A (object): 7     Pass

Another difference between Python 3 and Python 2 is that Python 3 can be used to directly use super (). XXX instead of super (Class, self). XXX:

 1  #   default , Python 3  2  class   B (A):  3  def   add (self, x):  4   super (). Ad D (x)  5  6  #   Python 2  7  class   B (A ):  8  def   add (self, x):  9  super (B, self). Add (x) 

So, if you're using Python 2, remember to replace the super () of this article with Suepr (Class, self).

If there are other cases that are incompatible with Python 2, I will mention it in the article.

Single inheritance

In single-Inheritance , super is, as you might think, primarily used to invoke the methods of the parent class.

classA:def __init__(self): SELF.N= 2defAdd (Self, m):Print('Self is {0} @a.add'. Format ( self) SELF.N+=mclassB (A):def __init__(self): SELF.N= 3defAdd (Self, m):Print('Self is {0} @b.add'. Format (self) super (). Add (m) SELF.N+ = 3

What do you think is the value of B.N after executing the code below?

b = B () B.add (2)print(B.N)

The results of the implementation are as follows:

 is <__main__. B object at 0x106c49b38> is <__main__. B object at 0x106c49b38> @a.add8

The results illustrate two questions:

    • 1,Super (). Add (m) does call the Add method of parent Class A .
    • 2,Super (). Add (m) when calling the parent class method def add (self, m), at this point in the parent class, self is not an instance of the parent class, but the child class, so the result after B.add (2) is 5 instead of 4 。

Don't know if this result is the same as you think? Let's look at a multi-inheritance example.

Multiple inheritance

This time we'll define a class C, a class D:

classC (A):def __init__(self): SELF.N= 4defAdd (Self, m):Print('Self is {0} @c.add'. Format (self) super (). Add (m) SELF.N+ = 4classD (B, C):def __init__(self): SELF.N= 5defAdd (Self, m):Print('Self is {0} @d.add'. Format (self) super (). Add (m) SELF.N+ = 5

What does the following code output?

D = D () D.add (2)print(D.N)

The output of this time is as follows:

 is <__main__. D object at 0x10ce10e48> is <__main__. D object at 0x10ce10e48> is <__main__. D object at 0x10ce10e48> is <__main__. D object at 0x10ce10e48> @a.add19

Did you say it right? You might think the output of the above code is similar:

 is <__main__. D object at 0x10ce10e48> is <__main__. D object at 0x10ce10e48> is <__main__. D object at 0x10ce10e48> @a.add15

Why is it different from what we expected? Here we will look at the mystery of super.

Super is a class

When we call super (), we actually instantiate a super class. You see, super is a class, not a keyword or a function, and other data structures:

class Pass ... >>> s = super (A)>>> type (s)<class'super' >>>>

In most cases, super contains two very important information: one MRO and one class in MRO. When you call Super in the following ways:

Super (A_type, obj)

MRO refers to the MRO of type (obj), the class in MRO is A_type, while isinstance (obj, a_type) = = True.

When this is called:

Super (Type1, type2)

MRO refers to type2 MRO, the class in MRO is type1, while Issubclass (type2, type1) = = True.

So, what did super () actually do? To put it simply: to provide a MRO and a Class C in the MRO , super () will return an object that looks up a method from a class after C in the MRO.

That is, the lookup method is not looked up from all MRO classes as usual, but rather from the tail of the MRO .

For example, there is an MRO:

[A, B, C, D, E, Object]

The following call:

Super (C, A). Foo ()

Super will only look for after C, that is: The foo method is only found in D or E or object .

How super works in multiple inheritance

And go back to the front.

D = D () D.add (2)print(D.N)

Now you may have a little bit of a reason why the output would be like this

 is <__main__. D object at 0x10ce10e48> is <__main__. D object at 0x10ce10e48> is <__main__. D object at 0x10ce10e48> is <__main__. D object at 0x10ce10e48> @a.add19

Let's take a concrete look at the following:

  • The MRO for D is: [D, B, C, A, Object]. Note: You can view The MRO information for D through D.mro () (Python 2 using d.__mro__)

  • Detailed code analysis is as follows:

    classA:def __init__(self): SELF.N= 2defAdd (Self, m):#Fourth Step        #from the super in D.add        #Self = = d, SELF.N = = D.N = = 5        Print('Self is {0} @a.add'. Format ( self) SELF.N+=m#D.N = = 7classB (A):def __init__(self): SELF.N= 3defAdd (Self, m):#Step Two        #from the super in D.add        #Self = = d, SELF.N = = D.N = = 5        Print('Self is {0} @b.add'. Format ( self)#equivalent to Suepr (B, self). Add (M)        #Self 's MRO is [D, B, C, A, Object]        #find the Add method from [C, A, Object] after Bsuper (). Add (M)#Sixth Step        #D.N = OneSELF.N + = 3#D.N =classC (A):def __init__(self): SELF.N= 4defAdd (Self, m):#Step three        #from the super in B.add        #Self = = d, SELF.N = = D.N = = 5        Print('Self is {0} @c.add'. Format ( self)#equivalent to Suepr (C, self). Add (M)        #Self 's MRO is [D, B, C, A, Object]        #find the Add method from [A, Object] after Csuper (). Add (M)#Fifth Step        #D.N = 7SELF.N + = 4#D.N = OneclassD (B, C):def __init__(self): SELF.N= 5defAdd (Self, m):#The first step        Print('Self is {0} @d.add'. Format ( self)#equivalent to Super (D, self). Add (M)        #Self 's MRO is [D, B, C, A, Object]        #find the Add method from [B, C, A, Object] after Dsuper (). Add (M)#Seventh Step        #D.N =SELF.N + = 5#SELF.N =D=D () D.add (2)Print(D.N)

    The call process diagram is as follows:

    D.MRO () = =[D, B, C, A, Object]d=D () D.N= = 5D.add (2)classD (B, C):classB (A):classC (A):classA:defAdd (Self, m):defAdd (Self, m):defAdd (Self, m):defAdd (Self, m): Super (). Add (M)1.---> Super (). Add (M) 2.---> Super (). Add (M) 3.---> SELF.N + =m SELF.N+ = 5 <------6. SELF.N + = 3 <----5. SELF.N + = 4 <----4. <--|        (14+5=19) (11+3=14) (7+4=11) (5+2=7)

Super in Python

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.