Prácticas comunes y problemas a evitar en la herencia de Python el problema del diamante, mixins y otros

Prácticas comunes y errores a evitar en la herencia de Python el problema del diamante, mixins y otros

La herencia, al igual que cualquier otro concepto en OOP, permite a los desarrolladores reutilizar el código y desarrollar soluciones de software elegantes y escalables. Teniendo en cuenta la vasta comunidad de Python, se han desarrollado múltiples módulos y lógicas. Sin embargo, al igual que con cualquier concepto, la herencia tiene algunos inconvenientes comunes, como el problema del diamante, los desafíos de la herencia de interfaces y el uso de Mixins.

Imagen del Autor

La herencia es un concepto fundamental en la programación orientada a objetos, donde una nueva clase hereda la clase de sus padres y reutiliza todos los métodos y variables definidos en la clase padre. Por lo tanto, promueve la reutilización de código, la escalabilidad y la modularidad.

Herencia Múltiple

La herencia múltiple permite que una clase herede atributos y métodos de más de una clase base. Esto significa que una clase derivada puede heredar múltiples clases simultáneamente.

class volar:  puede_volar = Trueclass nadar:  puede_nadar = Trueclass Pato(nadar, volar):    passd = Pato()print(d.puede_volar)   #Trueprint(d.puede_nadar)  #True

El ejemplo anterior es un ejemplo simple de herencia múltiple y cómo puede ser útil. Si queremos escribir un programa en Python sobre aves y mencionar algunas características especiales de forma independiente en clases y queremos reutilizarlas al hablar de una ave en particular, en el caso de un pato, por ejemplo, que puede nadar, volar y también caminar. En estos casos, la herencia múltiple es útil.

Hay lenguajes de programación que no admiten la herencia múltiple, aunque nos brinda flexibilidad para reutilizar el código, puede presentar nuevos desafíos como el problema del diamante, donde puede surgir confusión cuando una clase hereda de múltiples clases que tienen una base común.

Problema del Diamante

El problema del diamante surge particularmente cuando una clase hija hereda de múltiples clases padre que tienen una base común. Esto crea ambigüedad en el orden en que deben ejecutarse los métodos anulados. Veamos el siguiente ejemplo:

class Animal:    def hablar(self):        print("El animal habla")class Ave(Animal):    def hablar(self):        print("El ave trina")class Pez(Animal):    def hablar(self):        print("El pez burbujea")class Anfibio(Ave, Pez):    pass

Aquí, la clase Anfibio hereda tanto de las clases Pez como de las clases Ave, las cuales tienen una base común Animal. Como el método hablar se está anulando en ambas clases padre, se crea confusión para la clase Anfibio al invocar un método cuando se llama al método hablar. Por esta razón, algunos lenguajes de programación no admiten la herencia múltiple.

Pero Python, con la ayuda de la Linearización C3, aborda el problema del diamante utilizando el Orden de Resolución de Métodos (MRO, por sus siglas en inglés) y permite la herencia.

Orden de Resolución de Métodos (MRO)

En Python, la linearización C3 introducida en la versión 2.3 gobierna el Orden de Resolución de Métodos. Determina el orden en el que se deben buscar las clases para encontrar un método o variable apropiados. Los algoritmos de linearización C3 tienen en cuenta el orden de herencia y derivan la relación entre las clases.

Cuando se llama a un método, Python comienza buscándolo en la clase actual y, si no lo encuentra, sigue el MRO para buscarlo en las clases base. Y el MRO será de izquierda a derecha en caso de herencia múltiple y de abajo arriba en caso de herencia multinivel. Esto permite a los desarrolladores utilizar la herencia múltiple de manera efectiva sin ambigüedades.

Ahora si verificamos la salida, el método hablar de la clase Ave es referido primero ya que se llama primero.

Anfibio().hablar()# Salida - El ave trina

Aunque el MRO se asegura de que no tengamos errores, Mixins también pueden usarse para evitar la herencia múltiple y proporcionar funcionalidades adicionales.

Mixins

Los mixins son clases diseñadas para ser pequeñas y centrarse en una sola funcionalidad. Proporcionan una forma de compartir funcionalidades entre múltiples clases sin utilizar la herencia tradicional. Ayudan a prevenir el problema del diamante y evitan jerarquías profundas.

class JSONMixin:    
    def to_json(self):        
        import json        
        return json.dumps(self.__dict__)class Person:    
    def __init__(self, name, age):        
        self.name = name        
        self.age = ageclass JSONPerson(Person, JSONMixin):    
    passperson = JSONPerson("Alice", 30)print(person.to_json())

Otros problemas de herencia

  • Las clases heredadas están estrechamente acopladas a las clases base y cada vez que se modifica la funcionalidad de la clase base, es necesario probar todas las clases heredadas para garantizar un código sin errores. Por esta razón, es necesario estructurar la clase base y realizar herencias cuidadosas. Mantener métodos de envoltura en la clase base y, en la medida de lo posible, no heredar ni cambiar el código estático en la clase hija. No seleccionar una clase base frágil y no mantenible.
  • Anular incorrectamente un método o utilizar incorrectamente los métodos super() puede generar un código propenso a errores. No mantener jerarquías complejas ya que Python no obliga a la encapsulación y a las firmas de los métodos, puede haber problemas en tiempo de ejecución si no se realiza una anulación adecuada.
  • Herencia vs Composición: La herencia no es siempre la mejor solución, la composición en general crea un objeto complejo combinando objetos simples en lugar de heredar el comportamiento de clases hijas. Elija la composición en lugar de la herencia siempre que sea posible, ya que también promueve la reutilización y modularidad del código y evita problemas en la herencia como el problema del diamante, el acoplamiento estrecho y las inflexibilidades.

Eso es todo lo que tengo que decir sobre los problemas comunes de la herencia. Espero que esto ayude… Feliz codificación…

Referencias:https://www.python.org/download/releases/2.3/mro/

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

El papel proactivo de la IA en el combate a la corrupción en el gobierno

La reciente explosión de modelos generativos de Inteligencia Artificial (IA) ha centrado la atención del mundo en tem...

Inteligencia Artificial

De desbloquear generaciones confiables a través de la cadena de verificación Un salto en la ingeniería oportuna

Explora el método de ingeniería de la cadena de verificación, un paso importante para reducir las alucinaciones en lo...

Inteligencia Artificial

La recuperación del conocimiento toma el centro del escenario

Para hacer la transición de la implementación del consumidor a la empresarial para GenAI, las soluciones deben constr...

Inteligencia Artificial

Construye y entrena modelos de visión por computadora para detectar posiciones de autos en imágenes utilizando Amazon SageMaker y Amazon Rekognition

La visión por computadora (CV) es una de las aplicaciones más comunes del aprendizaje automático (ML) y el aprendizaj...

Inteligencia Artificial

¿Pueden los LLM reemplazar a los analistas de datos? Construyendo un analista potenciado por LLM

Creo que cada uno de nosotros se ha preguntado al menos una vez durante el año pasado si (o más bien cuándo) ChatGPT ...