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

| | | | | | | | | | | | | | |

# Mostrar el programa Python
# cómo funciona MRO


clase A:

def rk ( self ):

imprimir ( "En clase A" )

clase B (A):

def rk ( self ):

print ( "En clase B" )


r = B ()

r.rk ()

Salir:

En clase B 

En el ejemplo anterior, los métodos se llaman desde la clase B pero no desde 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
Con la herencia múltiple, los métodos se ejecutan en el orden especificado cuando se heredan las clases. Para los lenguajes que soportan la herencia simple, el orden de resolución de los métodos no es interesante, pero los lenguajes que soportan el orden de resolución de los métodos de herencia múltiple son muy importantes. Veamos otro ejemplo para obtener una comprensión más profunda del orden de resolución del método:


# Show Python program
# cómo funciona MRO


class R:

def rk ( self ):

imprimir ( " En la clase A " )

clase B (A):

def rk ( self ):

imprimir ( "En clase B" )

class C (A):

def rk ( < código clase = "color1"> self ):

imprimir ( " En clase C " )


# ordenar clases

clase D (B, C):

pass


r = D ()

r.rk ()

Salida :

En la clase B 

En el ejemplo anterior, usamos múltiples herencias tancia, y también se llama herencia de diamantes o diamante mortal de la muerte y se ve así:

Python sigue el orden de búsqueda en profundidad y, por lo tanto, termina llamando a un método de la clase A. Siguiendo el orden de resolución del método, el orden de búsqueda se ve así.
Clase D - > Clase B - > Clase C - > Clase A
Python sigue la profundidad de primer orden para resolver métodos y atributos. Entonces, en el ejemplo anterior, ejecuta el método en la clase B.

Estilo antiguo y nuevo de ordenar:
En la versión anterior de Python (2.1), estamos Se requiere usar las clases de estilo antiguo, pero en Python (3.x y 2.2) se nos requiere usar solo clases nuevas. Las nuevas clases de estilo son aquellas cuya primera clase principal hereda de la clase de objeto Python raíz.


# Clase de estilo antiguo

class OldStyleClass:

pasar


# Nueva clase de estilo

class NewStyleClass ( objeto ):

pasar

El orden de resolución del método (MRO) es diferente en ambos estilos de declaración. Las clases de estilo antiguo usan el algoritmo DLR o de izquierda a derecha de izquierda a derecha, mientras que las clases de estilo nuevo usan el algoritmo de linealización C3 para resolver el método a través de la herencia múltiple. p>

Algoritmo DLR
Mientras implementa múltiples herencias, Python crea una lista de clases para buscar porque necesita determinar qué método debe llamarse cuando se llama a la instancia. Como su nombre indica, el orden de resolución del método primero buscará la profundidad y luego irá de izquierda a derecha. Por ejemplo


class R:

pase


clase B:

pasar < /código>


clase C (A, B):

pase



clase D (B, A):

pas



clase E (C, D):

pasar

En el ejemplo anterior, el algoritmo primero mira la clase de instancia para el método llamado. Si no está allí, entonces mira al primer padre, si tampoco está allí, entonces se considera el padre-padre. Esto continúa hasta el final de la profundidad de la 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 se puede representar dos veces, por lo que el orden será D, B, A, C. Pero este algoritmo cambia de diferentes maneras y demostrando diferentes comportamientos en diferentes momentos. Entonces, Samuele Pedroni descubrió por primera vez la inconsistencia y presentó el algoritmo de linealización C3.

Algoritmo de linealización C3:
Algoritmo de linealización C3 — es un algoritmo que utiliza nuevas clases de estilo. Se utiliza para resolver la inconsistencia creada por el algoritmo DLR. Tiene ciertas restricciones:

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

El algoritmo de linealización C3 funciona según tres reglas:

  • El gráfico de herencia define la estructura de cómo se resuelven los métodos.
  • El usuario solo debe visitar la superclase después de visitar un método de clase local.
  • Monotonía

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


# Programa de Python para mostrar el orden
# en qué métodos se permitido


class A:

< clase de código = "palabra clave"> def rk ( self ):

print ( "In class A" < /código> )

clase B:

def rk ( self ):

print ( "In class B" )


# ordenar clases

class C (A, B):

def __ init __ ( self ):

imprimir ( " Constructor C " )

r = C ( )


# imprime el orden de búsqueda

print (C .__ mro __)

print (C.mro ())

Salir:

 Constructor de C ("clase & # 39; __ principal __. C & # 39; >, < clase & # 39; __ principal __. A & # 39; >, < clase & # 39; __ principal __. B & # 39; >, < clase & # 39; objeto & # 39; >) [< clase & # 39; __ principal __. C & # 39; >, < clase & # 39; __ principal __. A & # 39; >, < clase & # 39; __ principal __. B & # 39; >, < clase & # 39; objeto & # 39; >]