Class A (object): # A must is New-style class def __init__ (self): print "Enter A" print "Leave a" clas S B (c): # A-C def __init__ (self): print "Enter B" super (b, self). __init__ () print "Leave B"
In our impression, for super (b, self). __init__ () is the understanding that super (b, self) first finds the parent class of B (that is, Class A), then converts the object of Class B to the object of Class A, and then the Class A object "converted" calls its own __ The init__ function.
One day a colleague designed a relatively complex class architecture (let's not care if this class system is designed to be reasonable, just consider this example as a topic), the code is as follows
Code Snippet 4:
Class A (object): def __init__ (self): print "Enter a" print "Leave a" class B (object): def __init__ (self): print "Enter B" print "Leave B" class C (A): def __init__ (self): print "Enter C" super (C, self). __init__ () print "Leave C" Class D (A): def __init__ (self): print "Enter D" Super (D , self). __init__ () print "Leave D" class E (B, C): def __init__ (self): print "Enter E" b.__ Init__ (self) c.__init__ (self) print "Leave E" class F (E, D): def __init__ (self): print " Enter F " e.__init__ (self) d.__init__ (self) print" Leave F "
f = f (), the result is as follows:
Enter F Enter e enter B Leave B enter C Enter D Enter a leave a leave D leave C leave E enter D Enter a leave a leave D le Ave F
Obviously, the initialization functions of Class A and Class D are called repeatedly 2 times, which is not the result we expect! The result we expect is that at most only the initialization function of Class A is called 2 times-in fact, this is a problem that a multi-inheritance class system must face. We draw the class system of code snippet 4, such as:
Object
| \
| A
| / |
B C D
\ / |
E |
\ |
F
In our understanding of super, we can see that when invoking the initialization function of Class C, the initialization function of Class A is called, but the initialization function of Class D is actually called. Good one weird problem!
That is, the MRO records a sequence of class types for all the base classes of a class. Review the MRO records and discover that there are 7 elements, and 7 class names are:
F E B C D A Object
This explains why super (C, self) is used in c.__init__. __INIT__ () invokes the initialization function of Class D.???
Let's rewrite code snippet 4 to:
Code Snippet 5:
Class A (object): def __init__ (self): print "Enter a" super (A, self). __init__ () # new print "leave A " class B (object): def __init__ (self): print" Enter B " super (b, self). __init__ () # New Print "Leave B" class C (A): def __init__ (self): print "Enter C" super (C, self). __init__ () Print "Leave C" class D (A): def __init__ (self): print "Enter D" super (d, Self). __init__ () Print "Leave D" class E (B, C): def __init__ (self): print "Enter E" super (E, self). __init__ () # change print ' Leave e ' class F (E, D): def __init__ (self): print ' Enter F ' super (F, self). __ Init__ () # change print "Leave F"
f = f (), execution result:
Enter F Enter e enter B Enter C Enter D Enter a leave a leave D leave C leave B leave E leave F
As can be seen, the initialization of F not only completes all calls to the parent class, but also guarantees that the initialization function of each parent class is called only once.
Summary
1. Super is not a function, it is a class name, like Super (B, self) actually called the Super class initialization function,
produced a Super object;
2. The Super class initialization function does not do anything special, but simply records the class type and the concrete instance;
3. Super (B, self). The invocation of Func is not a Func function that invokes the parent class of the current class;
4. Python's multi-inheritance class ensures that functions of each parent class are called through the MRO method, and that each parent class function
Call only once (if each class uses Super);
5. Mixing super and unbound functions is a risky behavior, which can cause the parent class function that should be called to not call or a
A parent class function is called multiple times.
Some more in-depth questions: You can see that the order of the elements in print f.__mro__ is F E B C D A object, which is the base class lookup order for F, as to why this is the order, and how the python built-in multiple inheritance order is implemented, This involves the implementation of the MRO sequence,