logo

Orden de resolución del método en Python

En este tutorial, aprenderemos sobre el orden de resolución de los métodos, que también se conoce como MRO. Es un concepto esencial de la herencia de Python.

El orden de resolución del método describe la ruta de búsqueda de la clase que Pitón utiliza para obtener el método apropiado en las clases que contienen la herencia múltiple.

Introducción

Como sabemos, una clase que se hereda se llama subclase o clase principal, mientras que la clase que se hereda se conoce como clase secundaria o subclase. En la herencia múltiple, una clase puede constar de muchas funciones, por lo que se utiliza la técnica del orden de resolución del método para buscar el orden en el que se ejecuta la clase base.

En palabras simples: 'El método o los atributos se exploran en la clase actual, si el método no está presente en la clase actual, la búsqueda se mueve a las clases principales, y así sucesivamente'. Este es un ejemplo de una búsqueda en profundidad.

Desempeña un papel esencial en la herencia múltiple, donde el mismo método se puede encontrar en múltiples superclases.

Para entenderlo mejor, veamos cómo podemos usarlo.

lista de matrices y lista enlazada

Ejemplo -

 class A: def myname(self): print('I am a class A') class B(A): def myname(self): print('I am a class B') class C(A): def myname(self): print('I am a class C') c = C() print(c.myname()) 

Producción:

 I am a class C 

Explicación -

Hay una herencia múltiple en el código anterior. Hemos definido tres clases llamadas A, B y C, y estas clases tienen el mismo nombre llamado método mi nombre(). Creamos una clase de objeto C. El objeto invocaba la clase C, no la clase, mientras que la clase C heredó el método de la clase A.

El orden que se sigue en el código anterior es clase B - > clase A. Esta técnica se conoce como MRO (orden de resolución del método).

Entendamos otro ejemplo de herencia múltiple.

Ejemplo -

 class A: def myname(self): print(' I am a class A') class B(A): def myname(self): print(' I am a class B') class C(A): def myname(self): print('I am a class C') # classes ordering class D(B, C): pass d = D() d.myname() 

Producción:

 I am a class B 

Explicación -

En el código anterior, hemos creado otra clase D sin definir atributos de clase que heredaron las clases B y C. Cuando invocamos el método mi nombre(), va a la clase D y busca el mi nombre( ) función. Pero la clase D no tiene ninguna declaración. Por lo tanto, la búsqueda se transfiere a la clase B, obtiene el mi nombre() función y devuelve el resultado. La búsqueda se realizará de la siguiente manera.

 Class D -> Class B -> Class C -> Class A 

Si la clase B no tuviera un método, invocará el método de la clase C.

Aquí, le sugerimos que elimine el método de clase B y compruebe qué sucede. Al hacer esto, tendrá una idea de cómo funciona el método de resolución.

vikas divyakirti

Orden de estilo antiguo y nuevo

En la versión anterior de Python (2.1), estamos restringidos a usar las clases antiguas pero Pitón (2.2 y continuar), podemos usar las nuevas clases. De forma predeterminada, Python 3 tiene clases originales (nuevas). El primer padre de la nueva clase de estilo hereda de la clase 'objeto' raíz de Python. Veamos el siguiente ejemplo:

descargar sts

Ejemplo -

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

El estilo de declaración de ambas clases es diferente. En la resolución del método, las clases de estilo antiguo siguen el algoritmo de profundidad primero de izquierda a derecha (DLR), mientras que las clases de nuevo estilo utilizan el algoritmo de linealización C3 mientras realizan herencia múltiple.

Algoritmo DLR

Python crea una lista de clases mientras implementa la herencia múltiple entre las clases. Esa lista se utiliza para determinar qué método debe llamarse y cuál es el que invocan las instancias.

Podemos asumir que trabajando por su nombre ya que la resolución del método buscará primero en profundidad y luego irá de izquierda a derecha. A continuación se muestra el ejemplo.

Ejemplo -

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

Primero, el algoritmo buscará en la clase de instancia el método invocado. Si no se encuentra, pasa a los primeros padres, si tampoco se encuentra. Examinará al padre del padre. Esto continuará hasta el final de las clases heredadas.

En el ejemplo anterior, el orden de resolución del método será:

 class D -> class B -> class A -> class C -> class A 

Pero A no puede estar presente dos veces, por lo que...

 class D -> class B -> class A -> class C -> 

Este algoritmo muestra el comportamiento extraño en ese momento. Veamos el siguiente ejemplo.

Ejemplo -

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

Según el algoritmo DLR, el orden será E, C, D, B, A. Existe el intercambio de clases A y B en la clase C, lo cual es muy ambiguo. Significa que el algoritmo no conserva la propiedad de monotonicidad.

Samuele Perdoni fue la primera persona que descubrió una inconsistencia entre los algoritmos MRO.

Algoritmo de linealización C3

El algoritmo de linealización C3 es una mejor versión del algoritmo DLR porque elimina la inconsistencia. Este algoritmo tiene algunas restricciones que se detallan a continuación.

  • Los hijos deben preceder a sus padres.
  • Si una clase particular hereda de una o más clases, se guardan en el orden especificado en la tupla de la clase base.

Reglas del algoritmo de linealización C3

  • La estructura del orden de resolución del método se define mediante el gráfico de herencia.
  • El usuario debe visitar la superclase sólo después de visitar los métodos de las clases locales.
  • Preservar la monotonía

Método para la clase de resolución de método

Python proporciona dos formas de obtener el orden de resolución del método de una clase: __mro__ atributo o mro() método. Con la ayuda de estos métodos, podemos mostrar el orden del método en el que se resuelven.

Entendamos el siguiente ejemplo.

Ejemplo -

tff
 class A: def myname(self): print(' I am a class A') class B(A): def myname(self): print(' I am a class B') class C(A): def myname(self): print('I am a class C') # classes ordering class D(B, C): pass # it prints the lookup order print(D.__mro__) print(C.mro()) 

Producción:

 (, , , , ) [, , ] 

Como podemos ver en el resultado anterior, obtenemos el orden de resolución del método. De esta manera, el algoritmo de linealización C3 funciona para herencia múltiple.