CodeGym /Curso de Java /Python SELF ES /Orden de resolución de métodos (MRO)

Orden de resolución de métodos (MRO)

Python SELF ES
Nivel 16 , Lección 5
Disponible

11.1 Method Resolution Order

El orden de resolución de métodos (Method Resolution Order, MRO) determina la secuencia en la que Python busca métodos y atributos en la jerarquía de clases. Esto es especialmente importante cuando trabajamos con herencia múltiple, donde una clase puede heredar atributos y métodos de varios clases madre.

Básicamente, existe un orden estricto (o más bien, un algoritmo) según el cual Python recorre el árbol de herencia de clases. Este algoritmo asegura un orden de búsqueda de métodos correcto, que se puede describir de la siguiente manera:

Algoritmo de linealización C3

El algoritmo de linealización C3 determina el MRO combinando:

  • La propia clase.
  • La lista de clases madre en el orden en que se enumeran.
  • MRO de las clases madre en el mismo orden.

Reglas del algoritmo de linealización C3

  • Mantener el orden local de los métodos: si la clase A se menciona antes de la clase B, todos los métodos de la clase A deben ser considerados antes de los métodos de la clase B.
  • Respetar el orden en las clases madre: si la clase A es padre de la clase B, todos los métodos de la clase A deben ser considerados antes que los métodos de la clase B.
  • Respetar el orden de herencia: si la clase C es padre de dos o más clases, el orden de los métodos de la clase C debe preservarse en el MRO de todas esas clases.

Pasos del algoritmo:

Paso 1. Comenzamos con la propia clase:

Siempre comenzamos con la propia clase donde se llama al método.

Paso 2. Añadimos las clases base en el orden en que se enumeran:

Después de la clase actual, revisamos las clases base en el orden en que están indicadas en la herencia.

Paso 3. Recorremos las clases madre:

Buscamos campos y métodos allí.

Paso 4. Combinamos el MRO de las clases madre:

Si una misma clase base se hereda a través de varios caminos, se revisa solo una vez y en el orden correcto (todas las demás veces se omitirá).

Para aquellos ya familiarizados con el tema "Algoritmos y estructuras de datos", esto es una búsqueda en profundidad, no en amplitud.

11.2 Comprobación del MRO

En Python, se puede comprobar el orden de búsqueda de métodos y campos de una clase, usando el atributo __mro__ o la función mro().

Ejemplo:


class A:
    def method(self):
        print("A")
        
class B(A):
    def method(self):
        print("B")
        
class C(A):
    def method(self):
        print("C")
        
class D(B, C):
    def method(self):
        print("D")
        

# Comprobación del MRO
print(D.__mro__)
        

La salida será:


(<class '__main__.D'>, 
<class '__main__.B'>, 
<class '__main__.C'>,
<class '__main__.A'>,
<class 'object'>)
        

Esto muestra el orden en el que Python buscará métodos y atributos:

  • D: Python primero comprueba el método en la clase D.
  • B: Luego, Python comprueba el método en la clase B (la primera clase madre).
  • C: Si el método no se encuentra en la clase B, Python comprueba el método en la clase C (la segunda clase madre).
  • A: Si el método no se encuentra en las clases B y C, Python comprueba el método en la clase A.
  • object: Finalmente, Python comprueba el método en la clase base object.

11.3 Uso de super() con MRO

La función super() sigue el MRO para llamar a los métodos de las clases madre en el orden correcto. Consideremos un ejemplo de uso de super():

class A:
    def method(self):
        print("A")
        super().method()
        
class B(A):
    def method(self):
        print("B")
        super().method()
        
class C(A):
    def method(self):
        print("C")
        super().method()
        
class D(B, C):
    def method(self):
        print("D")
        super().method()
        
        
d = D()
d.method()
        

La salida será la siguiente:


D
B
C
A
        

Orden de búsqueda (MRO)

1. Llamada al método method de la clase D:

  • Python primero comprueba el método en la clase D y lo encuentra allí.
  • El método D.method() se ejecuta y muestra "D".
  • Luego se llama a super().method(), que sigue el MRO para llamar al siguiente método.

2. Llamada al método method de la clase B:

  • Según el MRO, la siguiente clase después de D es B.
  • El método B.method() se ejecuta y muestra "B".
  • Luego se llama a super().method(), que sigue el MRO para llamar al siguiente método.

3. Llamada al método method de la clase C:

  • La siguiente clase en el MRO después de B es C.
  • El método C.method() se ejecuta y muestra "C".
  • Luego se llama a super().method(), que sigue el MRO para llamar al siguiente método.

4. Llamada al método method de la clase A:

  • La siguiente clase en el MRO después de C es A.
  • El método A.method() se ejecuta y muestra "A".
  • Luego se llama a super().method(), pero como A no tiene métodos padres method (excepto object), la llamada termina sin más acciones.
1
Опрос
Herencia,  16 уровень,  5 лекция
недоступен
Herencia
Herencia
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION