Method Resolution Order is the rule Python uses to decide which version of a method to run when a class inherits from more than one parent class

When you write a class that inherits from multiple parent classes, Python needs a way to pick which parent's method to use if more than one parent has the same method name. Method Resolution Order (MRO) is that rule. It creates a list of classes in a specific sequence, and Python checks them in that order until it finds the method you called. Without MRO, Python would have no consistent way to handle this situation, and your code would behave unpredictably.

The sequence matters because it determines which parent class "wins" when there is a conflict. Python uses an algorithm called C3 Linearization to build this sequence. You do not have to understand the algorithm itself — what matters is that the order is consistent, predictable, and follows a clear rule: child classes come before parents, and parents are checked left to right in the order you listed them in the class definition.

Key Takeaways

  • Method Resolution Order is the sequence Python uses to find a method when multiple parent classes define the same method name.
  • You can see the MRO for any class by calling the ClassName.mro() method or by looking at the ClassName.__mro__ attribute.
  • The order is: the class itself first, then parent classes from left to right, then their parents, following a rule that prevents the same class from appearing twice.
  • If you call a method on an object and the class does not have it, Python walks down the MRO list until it finds a class that does.

How Python builds the Method Resolution Order

Python builds the MRO when you define a class. The process starts with the class itself, then adds its parent classes in the order you listed them. If those parents have their own parents, those get added next — but only if they have not already been added. This prevents a class from appearing twice in the list.

The rule is called C3 Linearization, and it guarantees three things: the class comes before its parents, parents appear in the order you listed them, and no class appears more than once. This means the MRO is always the same for a given class definition, and you can rely on it.

For example, if you define a class like class Child(Parent1, Parent2), the MRO will be [Child, Parent1, Parent2, object] — assuming neither Parent1 nor Parent2 inherit from anything other than the base object class. The object class is the root of all classes in Python and always appears at the end.

Viewing the Method Resolution Order for your class

You can see the MRO for any class in two ways. The first is to call the mro() method on the class itself: ClassName.mro(). This returns a list of classes in the order Python will check them. The second is to look at the __mro__ attribute: ClassName.__mro__. Both show the same information; the attribute is slightly faster if you are checking it many times.

When you print the MRO, you will see class names in square brackets, separated by commas. Reading from left to right tells you the order Python will use. The first class in the list is the class itself. The last is always object, the base class that all Python classes inherit from.

Checking the MRO is useful when you are debugging and need to understand why one method is running instead of another. If you are not sure which parent's version of a method is being called, print the MRO and trace through it from left to right.

What happens when Python looks for a method

When you call a method on an object, Python does not search randomly. It walks down the MRO list from left to right and stops at the first class that has that method. If the class itself has the method, it uses that. If not, it checks the first parent. If the first parent does not have it, it checks the second parent. This continues until Python finds the method or reaches the end of the list.

If Python reaches the end of the MRO without finding the method, you get an AttributeError. This error means the method does not exist in any class in the inheritance chain. The error message will tell you which class you called the method on and which method name was not found.

This is why the order of parent classes in your class definition matters. If you write class Child(Parent1, Parent2), Parent1's methods will be found before Parent2's methods. Swapping the order to class Child(Parent2, Parent1) changes which parent's method gets used.

Why Method Resolution Order matters in multiple inheritance

Multiple inheritance — when a class inherits from more than one parent — is powerful but risky. Without a clear rule for which parent's method to use, the same code could behave differently depending on which parent class the method came from. MRO solves this by making the rule explicit and consistent.

The most common problem MRO prevents is the "diamond problem." This happens when a class inherits from two parents that both inherit from the same grandparent. Without MRO, Python might try to run the grandparent's method twice. With MRO, the grandparent appears only once in the list, so the method runs exactly once.

Understanding MRO also helps you use the super() function correctly. super() calls the next method in the MRO, not necessarily the parent class. This is more flexible than calling the parent class by name, because it respects the full inheritance chain.

Common mistakes with Method Resolution Order

The most common mistake is assuming that MRO follows the order of parent classes in an obvious way without checking. If you have a complex inheritance structure with multiple levels, the MRO might not be what you expect. Always print it and verify before you assume.

Another mistake is changing the order of parent classes in a class definition without realizing it changes which methods get called. If you have class Child(Parent1, Parent2) and you later change it to class Child(Parent2, Parent1), the behavior of your code changes. Parent2's methods now take priority. This can break code that depends on Parent1's behavior.

A third mistake is not using super() when you override a method in a child class but still want the parent's version to run. If you call the parent class by name directly — like Parent.method(self) — you bypass the MRO and skip any other parents that might have that method. Using super() respects the full MRO and is more flexible.

How to use super() with Method Resolution Order

The super() function uses the MRO to call the next method in the chain. When you write super().method_name() inside a method, Python looks at the MRO, finds the current class, and calls the method from the next class in the list. This is safer than calling the parent class by name because it works correctly even if the inheritance structure changes.

super() is especially useful in multiple inheritance. If you have a class that inherits from two parents and both parents have an __init__ method, you can call both by using super() in each parent's __init__. The MRO ensures they are called in the right order and only once each.

For example, if you have class Child(Parent1, Parent2) and both parents have an __init__ method, you can write super().__init__() in Child's __init__. Python will call Parent1's __init__ first (because Parent1 comes first in the MRO). Inside Parent1's __init__, if you also call super().__init__(), Python will then call Parent2's __init__. This ensures both parents are initialized in the right order.

Frequently Asked Questions

How do I see the Method Resolution Order for a class I did not write?

Open a Python interpreter or script and import the class. Then call ClassName.mro() or print ClassName.__mro__. You will see the full list of classes in the order Python checks them. This works for any class, whether you wrote it or it came from a library.

Can I change the Method Resolution Order after I define a class?

No. The MRO is calculated when the class is defined and cannot be changed afterward. If you need a different MRO, you must redefine the class with a different parent order or inheritance structure. Changing the order of parent classes in the definition will change the MRO the next time the class is defined.

What does the object class at the end of the MRO do?

The object class is the base class of all Python classes. It appears at the end of every MRO and provides basic methods like __init__, __str__, and __repr__. If no other class in the MRO has a method, Python will use the one from object.

Why does Python use C3 Linearization instead of a simpler rule?

C3 Linearization prevents the same class from appearing twice in the MRO and ensures that parent classes are always checked in the order you listed them. Simpler rules can fail with certain inheritance structures, leading to unpredictable behavior. C3 Linearization guarantees consistency no matter how complex your inheritance is.