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, which is an algorithm called C3 in the later version of Python 2.3, which is described in the next blog post.