Orden de resolución de métodos en la herencia de Python

Orden de resolución de métodos: Orden 
de resolución de métodos (MRO) denota la forma en que un lenguaje de programación resuelve un método o atributo. Python admite clases que heredan de otras clases. La clase que se hereda se llama padre o superclase, mientras que la clase que hereda se llama hijo o subclase. En Python, el orden de resolución de métodos define el orden en el que se buscan las clases base al ejecutar un método. Primero, se busca el método o atributo dentro de una clase y luego sigue el orden que especificamos al heredar. Este orden también se denomina linealización de una clase y el conjunto de reglas se denomina MRO (Orden de resolución de métodos). Al heredar de otra clase, el intérprete necesita una forma de resolver los métodos que se llaman a través de una instancia. Por lo tanto, necesitamos el orden de resolución del método. Por ejemplo 
 

Python3

# Python program showing
# how MRO works
 
class A:
    def rk(self):
        print(" In class A")
class B(A):
    def rk(self):
        print(" In class B")
 
r = B()
r.rk()

Producción: 
 

 In class B

En el ejemplo anterior, los métodos que se invocan son de la clase B pero no de la clase A, y esto se debe al Orden de resolución de métodos (MRO). 
El orden que sigue en el código anterior es: clase B – > clase A 
En las herencias múltiples, los métodos se ejecutan según el orden especificado al heredar las clases. Para los lenguajes que admiten la herencia única, el orden de resolución del método no es interesante, pero los lenguajes que admiten el orden de resolución del método de herencia múltiple juegan un papel muy importante. Veamos otro ejemplo para comprender profundamente el orden de resolución del método: 
 

Python3

# Python program showing
# how MRO works
 
class A:
    def rk(self):
        print(" In class A")
class B(A):
    def rk(self):
        print(" In class B")
class C(A):
    def rk(self):
        print("In class C")
 
# classes ordering
class D(B, C):
    pass
    
r = D()
r.rk()

Producción: 
 

 In class B

En el ejemplo anterior, usamos herencias múltiples y también se llama herencia Diamond y se ve de la siguiente manera: 
 

Python sigue un orden de búsqueda en profundidad y, por lo tanto, termina llamando al método desde la clase A. Siguiendo el orden de resolución del método, el orden de búsqueda es el siguiente. 
Clase D -> Clase B -> Clase C -> Clase A 
Python sigue el orden de profundidad para resolver los métodos y atributos. Entonces, en el ejemplo anterior, ejecuta el método en la clase B. 
  
Orden de estilo antiguo y nuevo: 
en la versión anterior de Python (2.1) estamos obligados a usar clases de estilo antiguo, pero en Python (3.x y 2.2) estamos obligado a utilizar sólo nuevas clases. Las nuevas clases de estilo son aquellas cuyo primer padre hereda de la clase ‘objeto’ raíz de Python. 
 

Python3

# Old style class
class OldStyleClass:
    pass
 
# New style class
class NewStyleClass(object):
    pass

El orden de resolución del método (MRO) en ambos estilos de declaración es diferente. Las clases de estilo antiguo usan DLR o el algoritmo de izquierda a derecha que prioriza la profundidad, mientras que las clases de estilo nuevo usan el algoritmo de linealización C3 para la resolución del método al hacer herencias múltiples. 
  
Algoritmo DLR 
Durante la implementación de herencias múltiples, Python crea una lista de clases para buscar, ya que necesita resolver qué método debe llamarse cuando una instancia lo invoca. Como sugiere el nombre, el orden de resolución del método buscará primero en profundidad y luego de izquierda a derecha. Por ejemplo 
 

Python3

class A:
    pass
 
 
class B:
    pass
 
 
class C(A, B):
    pass
 
 
class D(B, A):
    pass
 
 
class E(C,D):
    pass

En el ejemplo anterior, el algoritmo primero busca en la clase de instancia el método invocado. Si no está presente, entonces busca en el primer padre, si eso tampoco está presente, entonces se busca en el padre del padre. Esto continúa hasta el final de la profundidad de clase y, finalmente, hasta el final de las clases heredadas. Entonces, el orden de resolución en nuestro último ejemplo será D, B, A, C, A. Pero A no puede estar presente dos veces, por lo tanto, el orden será D, B, A, C. Pero este algoritmo varía de diferentes maneras y mostrando diferentes comportamientos en diferentes momentos. Entonces, Samuele Pedroni descubrió por primera vez una inconsistencia e introdujo el algoritmo de linealización C3. 
  
Algoritmo de linealización C3: 
El algoritmo de linealización C3 es un algoritmo que utiliza clases de nuevo estilo. Se utiliza para eliminar una incoherencia creada por el algoritmo DLR. Tiene ciertas limitaciones que son: 
 

  • Los hijos preceden a sus padres.
  • Si una clase hereda de varias clases, se mantienen en el orden especificado en la tupla de la clase base.

El algoritmo de linealización C3 funciona con tres reglas: 
 

  • El gráfico de herencia determina la estructura del orden de resolución del método.
  • El usuario debe visitar la superclase solo después de visitar el método de las clases locales.
  • monotonicidad

  
Métodos para el orden de resolución de métodos (MRO) de una clase: 
para obtener el orden de resolución de métodos de una clase, podemos usar el atributo __mro__ o el método mro(). Al usar estos métodos, podemos mostrar el orden en que se resuelven los métodos. Por ejemplo 
 

Python3

# Python program to show the order
# in which methods are resolved
 
class A:
    def rk(self):
        print(" In class A")
class B:
    def rk(self):
        print(" In class B")
 
# classes ordering
class C(A, B):
    def __init__(self):
        print("Constructor C")
 
r = C()
 
# it prints the lookup order
print(C.__mro__)
print(C.mro())

Producción: 
 

Constructor C

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

[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

Publicación traducida automáticamente

Artículo escrito por bestharadhakrishna y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *