mro

Qu'est-ce que le MRO en Python ?

Qu'est-ce que le MRO ?

En Python, le MRO (Method Resolution Order, ou ordre de résolution des méthodes) indique dans quel ordre le langage parcourt les classes pour trouver une méthode ou un attribut.

C'est un concept particulièrement parlant lorsqu'on utilise l'héritage multiple. C'est grâce au MRO que Python sait exactement quelle méthode exécuter s'il existe des conflits ou des méthodes du même nom dans les classes parentes.

Depuis Python 2.3, l’algorithme utilisé par le MRO s'appelle la linéarisation C3. Ainsi, le comportement du MRO est prévisible : Python cherchera toujours de la classe enfant vers les parents, de la gauche vers la droite.

Comment afficher le MRO ?

Python permet d'afficher l'ordre de résolution d'une classe de deux manières très simples : 

  • L'attribut spécial __mro__ qui retourne un tuple

  • La méthode mro() qui retourne une liste

Le diamant

Le diamant

class A:
    def parler(self):
        print("Je suis la classe A")

class B(A):
    def parler(self):
        print("Je suis la classe B")

class C(A):
    def parler(self):
        print("Je suis la classe C")

# D hérite de B et C (de gauche à droite)
class D(B, C):
    pass

# Création d'une instance de D
mon_objet = D()
mon_objet.parler()  # Affiche : Je suis la classe B

# Affichage du MRO
print(D.__mro__)
# Résultat : (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
PYTHON
Un instant

Créez un compte pour exécuter ce code

Inscrivez-vous gratuitement pour modifier et exécuter du code Python directement dans votre navigateur.

  1. Python cherche d'abord la méthode parler() dans D sans la trouver

  2. Il cherche ensuite dans le premier parent (à gauche), B

  3. Il la trouve dans B et l'exécute

Si la méthode n'avait pas été dans B, il aurait continué dans C, et ainsi de suite.

Quand le MRO échoue avec une TypeError

Afin d'éviter les comportements imprévisibles, l'algorithme est strict. Si vous créez une hiérarchie illogique, Python refusera de créer la classe et lèvera une erreur.

class A:
    def parler(self):
        print("Je suis la classe A")

class B(A):
    def parler(self):
        print("Je suis la classe B")

# Erreur ! On demande de lire A avant B, alors que B hérite déjà de A
class C(A, B):
    def parler(self):
        print("Je suis la classe C")
PYTHON

Vous obtiendrez une exception au moment de la définition de C : TypeError: Cannot create a consistent method resolution order (MRO) for bases A, B.

Attention

L'algorithme C3 impose qu'une classe enfant (B) soit toujours parcourue avant sa classe parente (A). En déclarant class C(A, B), nous demandons à Python de parcourir A avant B, ce qui est contradictoire car B hérite de A.

Il est utile de comprendre le MRO pour bien assimiler le fonctionnement de la fonction super(), qui s'appuie sur le MRO pour les appels aux méthodes des classes parentes. De plus, la création de mixins est une pratique courante en Python (notamment dans les frameworks comme Django), et le MRO garantit que les fonctionnalités injectées via ces mixins s'ajoutent dans le bon ordre.

Bravo, tu es prêt à passer à la suite

Rechercher sur le site

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.