In Python's new class, the method parsing order is not a breadth-first algorithm, but a C3 algorithm, but in some cases, the results of the C3 algorithm coincide with the results of the breadth-first algorithm.
The following can be verified by code:
classNewstyleclassa (object): Var='New Style Class A'classNEWSTYLECLASSB (Newstyleclassa):PassclassNEWSTYLECLASSC (Newstyleclassa): Var='New Style Class C'classSubnewstyleclass (NEWSTYLECLASSB, NEWSTYLECLASSC):Passif __name__=='__main__': Print(Subnewstyleclass.mro ())Print(Subnewstyleclass.var)
Judging from the running results of the first code, the algorithm with the breadth-first result happens to be the same, but it just happens to be the same, not equal to the breadth-first algorithm.
[<class'__main__. Subnewstyleclass', <class'__main__. NEWSTYLECLASSB', <class'__main__. NEWSTYLECLASSC', <class'__main__. Newstyleclassa'object'>]new Style Class C
By modifying the code, you can confirm that:
Change NEWSTYLECLASSC to inherit from object
classNewstyleclassa (object): Var='New Style Class A'classNEWSTYLECLASSB (Newstyleclassa):PassclassNEWSTYLECLASSC (object): Var='New Style Class C'classSubnewstyleclass (NEWSTYLECLASSB, NEWSTYLECLASSC):Passif __name__=='__main__': Print(Subnewstyleclass.mro ())Print(Subnewstyleclass.var)
Run code output results
[<class'__main__. Subnewstyleclass', <class'__main__. NEWSTYLECLASSB', <class'__main__. Newstyleclassa', <class'__main__. NEWSTYLECLASSC'object'>]new Style Class A
From the results of the code run, it does not conform to the principle of breadth first.
About the C3 algorithm, as defined in Python advanced programming:
Take the head of the first list, that is, l[b,object], if it is not at the end of any table, add it to the linearization of the CLASSD and remove it from the list in the merge, otherwise find the header of the next list and remove it if it is a good table header. Note that the table header refers to the first element, and the tail refers to all elements except the header. such as [A,b,c,d,e,f],a is the table header, [b,c,d,e,f] is the tail.
The essence of the C3 algorithm is the merge, which constantly merges the sequence returned by the MRO () function as follows:
1. If the first element of the first sequence is the first element of another sequence, or no longer occurs again in another sequence, the element is merged into the final method parse sequence and removed from the entire sequence of the current operation.
2. If not, skip this element, look for the first element of the next list, repeat the 1 judgment rule
Use the first piece of code to step through the method parsing:
1. First print the NEWSTYLECLASSB and NEWSTYLECLASSC MRO () to get their succession sequence
[<class'__main__. NEWSTYLECLASSB', <class'__main__. Newstyleclassa', <class'object'>[ <class'__main__. NEWSTYLECLASSC';, <class'object';]
2. The inheritance sequence is parsed incrementally according to the C3 algorithm:
MRO (Subnewstyleclass)= [Subnewstyleclass] +Merge (MRO (NEWSTYLECLASSB), MRO (NEWSTYLECLASSC), [NEWSTYLECLASSB, NEWSTYLECLASSC])#based on the results of the first step, you can draw= [Subnewstyleclass] +merge ([Newstyleclassb, Newstyleclassa, Object], [NEWSTYLECLASSC, Newstyleclassa, Object], [NEWSTYLECLASSB, NEWSTYLECLASSC])#judging the current sequence of the merge first element newstyleclassb, the first element in the third sequence also exists, so it is merged into the final sequence and deleted:= [Subnewstyleclass, NEWSTYLECLASSB] +merge ([Newstyleclassa, Object], [NEWSTYLECLASSC, Newstyleclassa, Object], [NEWSTYLECLASSC])#determines the current sequence of the merge first element Newstyleclassa, exists in the second sequence, and is not the first element of the second sequence, skips #continue judging the first element in the second sequence, NEWSTYLECLASSC, exists in the third sequence, and is the first element, so it is merged into the final sequence and deleted:= [Subnewstyleclass, NEWSTYLECLASSB, NEWSTYLECLASSC] +merge ([Newstyleclassa, Object], [Newstyleclassa, Object])#The first element of the first sequence is now Newstyleclassa, so the Newstyleclassa is judged again. #Newstyleclassa is present in the second sequence and is the first element of the second sequence, so it is merged into the final sequence and deleted:= [Subnewstyleclass, NEWSTYLECLASSB, NEWSTYLECLASSC, Newstyleclassa] +merge ([object], [object])#The final object, which appears in the second sequence, is the first element, so it is merged into the final sequence and deleted, resulting in the final inheritance order:= [Subnewstyleclass, NEWSTYLECLASSB, NEWSTYLECLASSC, Newstyleclassa, Object)
The result of the parsing and the call to the Subnewstyleclass.mro () method print out the same result:
[<class'__main__. Subnewstyleclass', <class'__main__. NEWSTYLECLASSB', <class'__main__. NEWSTYLECLASSC', <class'__main__. Newstyleclassa';, <class'object';]
Use the second piece of code to step through the method parsing:
1. First print the NEWSTYLECLASSB and NEWSTYLECLASSC MRO () to get their succession sequence
[<class " __main__. NEWSTYLECLASSB ;, <class __main__. Newstyleclassa ;, <class object >][ < class __main__. NEWSTYLECLASSC ;, <class object ;]
2. The inheritance sequence is parsed incrementally according to the C3 algorithm:
MRO (Subnewstyleclass)= [Subnewstyleclass] +Merge (MRO (NEWSTYLECLASSB), MRO (NEWSTYLECLASSC), [NEWSTYLECLASSB, NEWSTYLECLASSC])#based on the results of the first step, you can draw= [Subnewstyleclass] +merge ([Newstyleclassb, Newstyleclassa, Object], [Newstyleclassc, Object], [NEWSTYLECLASSB, NEWSTYLECLASSC])#judging the current sequence of the merge first element newstyleclassb, the first element in the third sequence also exists, so it is merged into the final sequence and deleted:= [Subnewstyleclass, NEWSTYLECLASSB] +merge ([Newstyleclassa, Object], [Newstyleclassc, Object], [NEWSTYLECLASSC])#judging the current sequence of the merge the first element Newstyleclassa, which does not exist in subsequent sequences, merges it into the final sequence and deletes:= [Subnewstyleclass, NEWSTYLECLASSB, Newstyleclassa] +merge ([object], [Newstyleclassc, Object], [NEWSTYLECLASSC])#determines the current sequence of the merge the first element of object, which appears in the second sequence and is not the first element, skips #after skipping object, continue to judge the first element of the next sequence, that is, the first element of the second sequence, NEWSTYLECLASSC, appears in the third sequence and is the first element, so it is merged into the final sequence and deleted:= [Subnewstyleclass, NEWSTYLECLASSB, Newstyleclassa, NEWSTYLECLASSC] +merge ([object], [object])#The object is again judged, appears in the second sequence, and is the first element, so it is merged into the final sequence and deleted, resulting in the final inheritance order:= [Subnewstyleclass, NEWSTYLECLASSB, Newstyleclassa, NEWSTYLECLASSC, Object)
and the call Subnewstyleclass.mro () method prints out the same result
[<class'__main__. Subnewstyleclass', <class'__main__. NEWSTYLECLASSB', <class'__main__. Newstyleclassa', <class'__main__. NEWSTYLECLASSC';, <class'object';]
C3 algorithm inherited by Python's modern class