What is the relation between the Lookup Chain and MRO in Python?

104 views Asked by At

In Python, I've come across two concepts, the Lookup Chain and the Method Resolution Order (MRO), which seem related but I'm having trouble understanding their relationship. Could someone please clarify the connection between these two concepts?

  • Lookup Chain
  • Method Resolution Order MRO

From my understanding, the lookup chain refers to the order in which Python searches for attributes and methods in a class hierarchy. It determines the sequence of classes to be traversed during attribute and method resolution. On the other hand, the MRO is a specific algorithm used by Python to determine the order in which methods are resolved in a class hierarchy, especially in cases of multiple inheritance.

I'm seeking a clearer explanation of these two concepts.

  • Does the lookup chain play a role in the MRO algorithm?
  • How does the MRO ensure the correct method resolution in complex inheritance scenarios?
2

There are 2 answers

0
blhsing On

"Does the lookup chain play a role in the MRO algorithm?"

It's the other way around, that the MRO of the type of an object plays the sole deciding role in the lookup of an attribute of the object, as can be seen in the following line of CPython's implementation in _PyType_Lookup, called from _PyObject_GenericGetAttrWithDict:

res = find_name_in_mro(type, name, &error);
0
jsbueno On

mro, or Method Resolution Order, is the linearisation of the super classes in class, either in the presence of multiple-inheritance or with simple inheritance.

"Lookup chain" is a more loose expression, but will usually refer to how does Python look for a given attribute or method in an object, when retrieving an attribute (either with the . notation or with the use of getattr): it includes more things than the mro because the current class and super-classes are not the only place an attribute will be searched, and the list of superclasses is just one of the places the search takes place.

For example, if an attribute exists in an instance's __dict__ and is not a descriptor in the class, or any superclass of that instance, the instance value is used. To search for a descriptor with the same name, before picking the instance value, however, Python does search the current and all super-classes using the MRO. Also, if an attribute is not present in an instance and in no super-class, the lookup chain includes a call to __getattr__ (if it is defined), to try getting a computed value for that attribute.

In other words: the MRO is the order the current class and superclasses are traversed when looking for an attribute or method. The "lookup chain" encompasses all places an attribute will be searches, one of these places being the current class or superclasses: the point where the MRO is used.

Python's current MRO algorithm was defined back in Python 2.3 and is described here: https://www.python.org/download/releases/2.3/mro/