Home > Article > Backend Development > How do python subclasses use MRO in multiple inheritance?
In Python, when defining a class, you can specify its parent class. A subclass inherits all the properties and methods of its parent class and can add its own unique properties and methods.
However, if a class has multiple direct parent classes, there may be properties and methods with the same name between these parent classes. In order to correctly call these properties and methods, Python uses an algorithm called "Method Resolution Order" (Method Resolution Order, MRO) to determine the search order of properties and methods.
In Python 2.x, MRO is implemented using the depth-first search algorithm (DFS). There are some problems with this algorithm that cause the method call sequence to not be correctly parsed in some cases. For example:
class A: def foo(self): print("A.foo") class B(A): pass class C(A): def foo(self): print("C.foo") class D(B, C): pass d = D() d.foo() # 输出"A.foo",而不是"C.foo"
In the above code, class D inherits class B and class C, and class C overrides the foo() method of class A. Therefore, when calling the foo() method of object d, theoretically the foo() method in class C should be called first. However, since Python 2.x uses the DFS algorithm, it will traverse class B first, then class C, and finally class A. Therefore, the foo() method in class A is ultimately called, not the foo() method in class C.
In order to solve this problem, Python 2.3 introduced the C3 algorithm, which uses a topological sorting algorithm to calculate the MRO list to ensure the correctness when calling methods. The basic principle of the C3 algorithm is as follows:
The MRO list of new-style classes (that is, classes that explicitly inherit object or implicitly inherit object) is calculated according to the breadth-first search (BFS) algorithm.
For each class, its MRO list should meet the following three conditions:
The MRO list of subclasses should be ranked At the front of the MRO list of the parent class.
If two parent classes appear in the MRO list of a child class, their relative order in the list must be consistent with their appearance in the direct parent class of the child class. The relative order is the same.
A class cannot appear more than twice in its MRO list.
This algorithm can correctly handle the situation in the above example code, thereby ensuring the correctness when calling the method.
In Python 3, you can view the MRO list of a class through the __mro__
attribute. For example:
class A: def foo(self): print("A.foo") class B(A): pass class C(A): def foo(self): print("C.foo") class D(B, C): pass print(D.__mro__)
The output result is:
(025dcfa56ce70cf61f231bd7d6b09a90, d3d10dde313d07caf2874a0faa31cc27, 8a1d825241d138e74588411ff30b3bba, d65e71c32c2035ca4f3e3c46100a7a5f, 0b6b3070adce8118f880cf43f8bc8037)
Among them, 9feb4194ec50eecacec2aeb187aaba71
represents class D itself, d3d10dde313d07caf2874a0faa31cc27
and 264899d62e4ca0da0ab3f6eed2baa002
represent the parent of class D respectively Classes B and C, d65e71c32c2035ca4f3e3c46100a7a5f
represents the common parent class A of classes B and C, 0b6b3070adce8118f880cf43f8bc8037
represents all new-style classes base class. The order of this list is the order in which properties and methods are looked up when Python is running.
The above is the detailed content of How do python subclasses use MRO in multiple inheritance?. For more information, please follow other related articles on the PHP Chinese website!