The method of calling the parent class in the subclass can be the following A.spam (self) method.
classAObject):
defspam (self print ' a.spam '
class b (A):
def Span lang= "en-US" >spam (self print ' b.spam '
a.spam (self if __name__== ' __main__ ' :
b=b ()
b.spam ()
But the code above has a problem, if the parent class of B changes, and there are many subclasses of the parent class is not a , from A to C. Then the code is too much work. So the super method was adopted after the Python2.2 .
B (C): #相比之前的代码, you just need to change this line of code.
Spam (self):
' B.spam '
Super self). Spam ()
For the previous a.spam () usage . Let's look at one more example.
classA (Base):
def__init__(Self):
Base.__init__(Self)
print ' a.__init__ '
class B (Base):
def__init__(Self):
Base.__init__(Self)
print ' b.__init__ '
class C (A, B):
def __init__(self):
A.__init__(self)
B.__init__(self)
print ' c.__init__ '
if __name__==' __main__ ':
C=c ()
E:\python2.7.11\python.exe e:/py_prj/python_cookbook/chapter8.py
base.__init__
a.__init__
base.__init__
b.__init__
c.__init__
You can see that base.__init__ was called two times. We'll rewrite the code .
classBase (Object):
def__init__(Self):
print ' base.__init__ '
class A (Base):
def__init__(Self):
SuperASelf).__init__()
print ' a.__init__ '
class B (Base):
def__init__(Self):
super (B, self __init__ ()
print Span lang= "en-us" > ' b.__init__ '
class c (A, B):
def __init__ (self super (C, self __init__ ()
print Span lang= "en-us" > ' c.__init__ '
E:\python2.7.11\python.exe e:/py_prj/python_cookbook/chapter8.py
base.__init__
b.__init__
a.__init__
c.__init__
After changing to Super,base.__init__ was only called once. The reason is that the call to super () is based on the MRO list. Python finds the base class from left to right on the MRO list. Until the first class that matches this property is found. The MRO list can be obtained by viewing __mro__
C.__mro__
(<class ' __main__. C ';, <class ' __main__. A ';, <class ' __main__. B ';, <class ' __main__. Base ';, <type ' object ' >)
So what is the MRO table and how does the MRO table work ?
Mro:method Resolution Order. The function is to search the current class and base class and determine the order. There are two types in Python: Classic and Modern. The difference is that the new class inherits from the object
First look at the classic class:
classFather ():
defShow_infor (Self):
print ' father.show_infor '
class Child1 (Father):
Pass
Class Child2 (Father):
def show_infor (self):
print ' child2.show_infor '
class grandchildren (child1,child2):
Pass
If __name__==' __main__ ':
G=grandchildren ()
G.show_infor ()
The results of the operation are as follows:
E:\python2.7.11\python.exe e:/py_prj/python_cookbook/chapter8.py
Father.show_infor
grandchildren inherits from Child1 and Child2,Child1 and Child2 inherit from Father. Child2 and father all have functions that implement Show_infor. But eventually only the Father function was run. And the Child2 is not running.
Look at the order of MRO:
Inspect.getmro (grandchildren)
(<class __main__. grandchildren at 0x0166f228> <class __main__. Child1 at 0x0164eea0> <class __main__. Father at 0x0164ec70> <class __main__. Child2 at 0x0166fd88>)
The order is grandchildren->child1->father->child2.
The inheritance relationship of this class and the invocation relationship reference. In fact, the true inheritance relationship is grandchildren->child1->father->child2->father. The first result of preserving only the repeating class is grandchildren-> Child1->father->child2. But this kind of inheritance relationship. The show_infor in the Child2 that caused the subclass cannot be called. So this is the problem with the classic class.
In order to solve this problem of classical class, we introduced the new class. or the previous code. The only thing that needs to change is that Father (object) Father here inherits from object. What does the result look like?
E:\python2.7.11\python.exe e:/py_prj/python_cookbook/chapter8.py
Child2.show_infor
(<class ' __main__. grandchildren ';, <class ' __main__. Child1 ';, <class ' __main__. Child2 ';, <class ' __main__. Father ';, <type ' object ' >)
You can see that the result is called the Child2 show_infor. The final order of calls is Grandchildren->child1->child2->father->object.
The order of calls in the new class is as follows. However, unlike the classic class, the repeating class retains only the last one. That is, the initial call order is
Grandchildren->child1->father->object->child2->father->object
Because only the last repeating class is preserved, the final call order is grandchildren->child1->child2->father->object.
The Call of the new class can make the Child2 function get called.
Is there a problem with the new class? Let's look at an example:
Class x (Object):p
Class Y (object):p
Class A (x, y):p
Class B (y,x):p
Class C (A, b):p
The order in which this example is accessed is C->a->x->object->y->object->b->y->object->x->object
Only the last result of a repeating element is c->a->b->y->x->object. This is the order of C.
Let's look at the order of C parent Class A, B:
A:a->x->y->object
B:b->y->x->object
You can see that the X, Y inheritance of C and a is reversed, meaning that C changes the order of the parent Class A as a subclass. In Python the neutron class cannot change the way the base class is. If the code above is executed, an error will also be reported.
The method of C3 was adopted after python2.3.
Since C3 involves the method of graph theory, here is only a brief introduction:
Let's start with a list of l[c]=[c1,c2,c3. CN]. Where the C1 is the head, the rear c2,c3,cn are the tails. C3 's search order follows the following guidelines:
1 Examine the head element of the first list (such as L[B1] 's head), as H.
2 if H does not appear at the end of the other list, output it and remove it from all lists, then go back to step 1; otherwise, take the head of the next list as H and proceed with the step.
3 Repeat the above steps until the list is empty, or you can no longer find out which elements to output. If this is the case, then the algorithm ends; if it is the latter case, it means that the inheritance relationship cannot be built, and Python throws an exception.
For example, a is calculated as follows:
L[a] = [A] + merge (L[x], l[y], [X], [Y]) First step
= [A] + merge ([X, Object], [Y, Object], [x], [Y]) The second step
= [A, X] + merge ([object], [Y, Object], [y]) step three
= [A, X, Y] + merge ([object], [object]) Fourth step
= [A, X, Y, Object]
In the third step, because object is at the end of [Y,object], skip this list to get Y and remove y from the other list. The final result is a,x,y,object. And the same process for B.
Look at C again.
L[C] = [C] + merge (L[a], l[b], [A], [B])
= [C] + merge ([A, X, Y, Object], [B, Y, X, Object], [a], [B]) 1
= [C, A] + merge ([X, Y, Object], [B, Y, X, Object], [b]) 2
= [C, A, B] + merge ([X, Y, Object], [Y, X, Object]) 3
In the second step, because X exists at the end of [B, Y, X, Object], and Y exists at the end of the merge ([X, Y, Object], it is not possible to construct an inheritance relationship without ambiguity. System error
Python Cookbook Third Edition study note 11: Classes and Objects (ii) methods of calling the parent class