The super function is used to solve diamond inheritance.
First, the inheritance of Python and the invocation of the parent class member
Parent class:
class Base (object): def __init__ (self): print ("base init". ")
Normal method calls the parent class:
class Leaf (Base): def __init__ (self): base.__init__ (self) print ("Leaf init. ")
The Super method calls the parent class:
class Leaf (Base): def __init__ (self): super (leaf, self). __init__ () print ("leaf init". ")
Ii. Diamond Inheritance
Calling the parent class using the normal method initializes the base class 2 times. Use super to solve the problem.
classBase (Object): def __init__ (self): print ("Base Init")classMedium1 (Base): def __init__ (self): Super (MEDIUM1, self). __init__ () print ("MEDIUM1 Init")classMedium2 (Base): def __init__ (self): Super (Medium2, self). __init__ () print ("Medium2 Init")classLeaf (Medium1, Medium2): Def __init__ (self): Super (Leaf, self). __init__ () print ("Leaf Init") Leaf= Leaf ()
Three, super working principle
To understand the super principle, we need to understand the MRO first. MRO is the abbreviation for method resolution order, which indicates the order of member resolution in the class inheritance system. In Python, each class has a class method for the MRO. Let's take a look at what the leaf MRO looks like in diamond succession:
print (Leaf.mro ()) [ <class " __main__. Leaf ", <class " __main__. MEDIUM1 ", <class " __main__. Medium2 ", <class " __main__. Base ", <class " object ";]
You can see that the MRO method returns a list of ancestor classes. Each ancestor of the leaf appears once, which is the order in which super finds members in the parent class.
By Mro,python, the multi-inheritance graph structure is cleverly transformed into the order structure of the list. Super in the inheritance system in the upward search process, into the MRO in the right linear lookup process, any class will only be processed once.
In this way, Python solves the 2 major challenges of multiple inheritance:
1. Find the order problem. From the Leaf's MRO order, it can be seen that if the leaf class accesses the parent class members through Super, then the members of the MEDIUM1 will be first accessed before Medium2. If both MEDIUM1 and Medium2 are not found, then finally to the base to find.
2. Multiple initialization problems with diamond inheritance. In the MRO list, the base class appears only once. In fact, any class will only appear once in the MRO list. This ensures that the method of any ancestor class is executed only once during super-up invocation.
Iv. How to use Super
Usage one, super (type, obj)
When we write this super in the __init__ of the Leaf:
class Medium1 (Base): def __init__ (self): super (MEDIUM1, self). __init__ () print (" MEDIUM1 init")
Super (Leaf, self). __init__ () means that:
- Get the MRO of the self-owned class, which is [Leaf, Medium1, Medium2, Base]
- Starting with a class on the right side of the leaf in the MRO, look for the __init__ function in turn. This is the beginning of the MEDIUM1 search.
- Once found, bind the found __init__ function to the Self object and return
As you can see from this execution process, if we do not want to invoke MEDIUM1 's __init__ and want to invoke Medium2 's __init__, then super should be written as: Super (MEDIUM1, self) __init__ ()
Usage II,super (Type, type2)
class Leaf (MEDIUM1, Medium2): def __new__ (CLS): = Super (Leaf, CLS). __new__ (CLS) print ( "Leaf new") return obj
The super (Leaf, CLS). __new__ (CLS) means that:
- Get MRO for this class of CLS, also [Leaf, Medium1, Medium2, Base]
- Start with a class on the right side of the leaf in the MRO, looking for the __new__ function in turn
- Once found, returns the " unbound " __new__ function
Because a non-binding function object is returned, the first argument of the function cannot be omitted when called. This is also the reason for the need to pass in the parameter CLS when calling __new__ here, and again, if we want to start looking from somewhere in the MRO, we just need to modify the first parameter of super.
Python object-oriented 11 super function