ProgramaciónDesarrollador Backend

¿Qué son los decoradores de clases en Python? ¿Cómo se pueden usar para modificar o complementar la funcionalidad de las clases? Proporcione un ejemplo y hable sobre los posibles matices.

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

Un decorador de clase es una función que toma una clase como argumento y devuelve una clase modificada o completamente nueva. Con ellos, se pueden agregar dinámicamente métodos, cambiar el comportamiento de métodos existentes o incluso devolver una subclase que amplíe la funcionalidad de la clase original.

Ejemplo simple de decorador de clase:

def add_repr(cls): def __repr__(self): return f'<{cls.__name__}: {self.__dict__}>' cls.__repr__ = __repr__ return cls @add_repr class Point: def __init__(self, x, y): self.x = x self.y = y p = Point(3, 4) print(p) # <Point: {'x': 3, 'y': 4}>
  • El decorador add_repr agrega dinámicamente el método __repr__ a todas las clases a las que se aplica.

Matices:

  • Los decoradores de clases pueden devolver no solo envolturas en la clase, sino también completamente envueltas (por ejemplo, clases proxy o herederos).
  • Se pueden obtener errores si el decorador no admite argumentos *args y **kwargs, que se utilizan al crear instancias de la clase.

Pregunta engañosa.

¿Qué ocurrirá si se aplican dos decoradores de clase uno tras otro? ¿Siempre es obvio el orden de su aplicación?

Respuesta:

Los decoradores se aplican "de abajo hacia arriba": primero se aplica el decorador que está directamente sobre la declaración de la clase, luego el siguiente más arriba, etc. El orden es MUY IMPORTANTE, ya que el resultado del primer decorador se pasa al segundo y así sucesivamente.

@dec1 @dec2 class Test: ... # Equivalente a: # Test = dec1(dec2(Test))

Ejemplos de errores reales debido a la falta de conocimiento sobre los matices del tema.


Historia

En una aplicación de e-commerce, se quería registrar los métodos de la clase, pero accidentalmente se devolvió el objeto incorrecto desde el decorador, y los métodos perdieron su atributo de clase, lo que rompió la herencia y causó fallos en el modelo.


Historia

En un proyecto para la autogeneración de nuevos métodos, se utilizó un decorador adicional, pero se olvidó llamar a super() al devolver la subclase. Esto resultó en una violación de la jerarquía y del MRO, causando que las llamadas al clase base en las derivadas no funcionaran.


Historia

En un data pipeline, se intentó envolver las clases con varios decoradores (registrador, rastreador de cambios), pero debido a un orden incorrecto de aplicación, se produjo un conflicto de nombres de métodos, lo que llevó a errores en producción debido a métodos "perdidos".