Home >Backend Development >Python Tutorial >How Does Method Resolution Order (MRO) Differ Between Legacy and New-Style Classes in Python?
Method Resolution Order (MRO) Differences between Legacy and New-Style Classes
New-style classes in Python introduced a significant change in the method resolution order (MRO) compared to legacy classes. While the provided example demonstrates MRO resolution correctly for new-style classes, let's delve into the subtle differences that distinguish the two approaches.
The key difference emerges when an ancestor class appears multiple times in the "naive" depth-first resolution order. Consider the following "diamond inheritance" case:
class A: x = 'a' class B(A): pass class C(A): x = 'c' class D(B, C): pass
Using legacy classes, the resolution order would be: D - B - A - C - A. In this order, A is encountered first, resulting in the definition of 'x' being hidden by the subsequent definition in C.
D.x => 'a'
However, new-style classes adopt a revised MRO:
D.__mro__ = (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
This order ensures that ancestor classes appear only once and after all their subclasses. Consequently, overrides like C's modification of 'x' take precedence.
D.x => 'c'
By avoiding multiple appearances of ancestor classes in the resolution order, this approach eliminates ambiguities and ensures intuitive behavior in complex inheritance hierarchies. This is why old-style classes should generally be avoided in favor of new-style classes, especially when dealing with multiple inheritance and diamond-like patterns.
The above is the detailed content of How Does Method Resolution Order (MRO) Differ Between Legacy and New-Style Classes in Python?. For more information, please follow other related articles on the PHP Chinese website!