Method Resolution Order is the order Python uses to search for a method or attribute in a class hierarchy
When you call a method on an object in Python, the language doesn't just look in that object's class. It searches through a chain of parent classes in a specific sequence. That sequence is called Method Resolution Order, or MRO. Understanding MRO matters because it determines which version of a method actually runs when multiple classes define the same method name — and it prevents Python from searching the same parent class twice in complex inheritance trees.
Python uses an algorithm called C3 Linearization to build this order. You don't need to memorize the algorithm, but you do need to know how to read the order Python creates, because when your code behaves unexpectedly, MRO is often the reason.
Key Takeaways
- Method Resolution Order is the sequence Python follows when searching for a method, starting with the object's own class and moving through parent classes in a specific order.
- You can view a class's MRO by calling the mro() method or printing the __mro__ attribute, which shows you exactly which class Python will check at each step.
- In single inheritance (one parent class), MRO is straightforward: the child class, then the parent, then object; in multiple inheritance, the order depends on how you list parent classes in the class definition.
- When two parent classes define the same method, the parent listed first in the class definition takes priority, and Python guarantees each class is searched only once.
- MRO errors happen when parent classes are listed in an order that creates an impossible search sequence; Python will raise a TypeError rather than guess which order you meant.
How Python searches for a method step by step
When you write code like my_object.some_method(), Python doesn't immediately run the method. First, it searches for where that method is defined. The search always starts with the object's own class. If the method isn't there, Python moves to the parent class. If it's not there either, Python moves to that parent's parent, and so on, until it reaches the base class object that all Python classes inherit from.
This search path is the Method Resolution Order. In a simple case with one parent class, the order is obvious: child class, parent class, then object. But when a class has multiple parents, or when parents themselves have parents, the order becomes less obvious — and that's where MRO becomes important to understand.
Python guarantees that each class in the hierarchy is checked exactly once, in a consistent order. This prevents infinite loops and ensures that the same method doesn't run twice by accident. The C3 Linearization algorithm is what builds this order, and it respects two rules: a child class is always checked before its parents, and if a class has multiple parents, they are checked in the order you listed them.
Viewing the Method Resolution Order for your classes
You can see the MRO for any class in two ways. The first is to call the mro() method on the class itself. For example, if you have a class called Dog, you would type Dog.mro() and Python prints a list showing the exact order it searches. The second way is to access the __mro__ attribute, which gives you the same information as a tuple instead of a list.
Here's a concrete example. Suppose you define a parent class called Animal and a child class called Dog that inherits from Animal. When you call Dog.mro(), Python returns [<class 'Dog'>, <class 'Animal'>, <class 'object'>]. This tells you that Python will search the Dog class first, then Animal, then the built-in object class. If Dog doesn't define a method but Animal does, that method runs.
Getting in the habit of checking MRO when inheritance gets complicated saves hours of debugging. Print it out, look at the order, and trace through where Python will find each method you call.
Single inheritance and why MRO is straightforward
In single inheritance, each class has only one parent. The MRO is simple: the child class, then the parent, then the parent's parent, all the way up to object. There are no choices to make and no conflicts to resolve.
For example, if you have Vehicle as a parent, Car as a child of Vehicle, and SportsCar as a child of Car, the MRO for SportsCar is [SportsCar, Car, Vehicle, object]. Python checks SportsCar first, then Car, then Vehicle, then object. This order never changes and never causes surprises.
Most of the time, single inheritance is all you need. The MRO becomes relevant when you move to multiple inheritance, where one class has two or more parents.
Multiple inheritance and how parent order matters
Multiple inheritance is when a class inherits from more than one parent. The order you list those parents in the class definition determines the order Python searches them. If you write class Dog(Animal, Pet):, Python will search Animal before Pet. If you write class Dog(Pet, Animal):, Python will search Pet first.
This matters because if both Animal and Pet define a method with the same name, the one in the first parent class runs. Python doesn't merge the methods or ask you to choose — it uses the MRO to pick one automatically. The first parent in the list wins.
When you call Dog.mro() with multiple parents, you see the order Python actually uses. It's not just the parents listed in order — Python interleaves them with their own parents in a way that respects the C3 Linearization rules. The result is a single, unambiguous list that Python follows every time.
When MRO creates an error and what it means
Sometimes Python cannot build a valid MRO and raises a TypeError. This happens when the order you've specified for parent classes creates a logical impossibility. For example, if you try to make a class inherit from parents in an order that contradicts how those parents inherit from each other, Python stops and tells you the MRO is invalid.
A common cause is listing parents in an order that violates the rule "a class must come before its parents in the search order." If parent A inherits from parent B, but you list B before A in your child class definition, Python detects the conflict and refuses to create the class.
When you see an MRO error, the fix is to reorder your parent classes so that the inheritance chain makes sense. Python is being strict on purpose — it's better to fail at class definition time than to have unpredictable behavior later. Read the error message, check the order of your parents, and make sure each parent comes before its own parents in the list.
Why MRO matters in real code
MRO becomes critical when you use the super() function. super() doesn't call the parent class directly — it calls the next class in the MRO. If you misunderstand the MRO, you'll call the wrong method or skip a class you meant to include.
It also matters when debugging. If a method runs and you don't understand why, or if a method doesn't run when you expected it to, the MRO is the first place to look. Print it out, trace through the order, and you'll see exactly which class Python found the method in.
In most single-inheritance code, MRO stays invisible and you don't think about it. But the moment you use multiple inheritance or call super(), understanding MRO shifts from optional to necessary. It's the difference between code that works by accident and code you can predict and maintain.
Frequently Asked Questions
How do I see the Method Resolution Order for a class I didn't write?
Call ClassName.mro() or print ClassName.__mro__ in the Python interpreter. Both show you the exact order Python uses to search that class and all its parents. This works for any class, whether you wrote it or it came from a library.
Does the order of parent classes matter in single inheritance?
No. Single inheritance means one parent, so there is no choice to make. The MRO is always the child, then the parent, then up the chain. Multiple inheritance is where parent order matters.
What happens if two parent classes define the same method?
Python uses the MRO to pick one. The parent listed first in the class definition takes priority. Python searches that parent first, finds the method, and stops. The method in the second parent is never called unless you explicitly call it using super() or by naming the class directly.
Can I change the Method Resolution Order after I define a class?
No. The MRO is built when the class is defined and doesn't change. If you need a different MRO, you must redefine the class with parents in a different order, or restructure your inheritance hierarchy.
Why does Python use C3 Linearization instead of a simpler algorithm?
Simpler algorithms can search the same class twice or violate the rule that a child must be checked before its parents. C3 Linearization guarantees each class is visited exactly once and respects the inheritance order you specified. This prevents bugs and makes behavior predictable.