ProgramaciónDesarrollador Backend

Explique cómo funcionan los decoradores en Python. ¿Cuál es su principal utilidad, cómo se implementan y qué detalles pueden surgir en su uso?

Supere entrevistas con el asistente de IA Hintsage

Respuesta

Los decoradores son funciones que aceptan otra función y devuelven una nueva función con comportamiento extendido o modificado. Se utilizan a menudo para registro, verificación de permisos, almacenamiento en caché, tiempo de ejecución y más.

Los decoradores se implementan usando cierres (closure) o clases que implementan el método __call__. La sintaxis clásica es:

# Decorador simple def simple_decorator(func): def wrapper(*args, **kwargs): print("Antes de llamar a la función") result = func(*args, **kwargs) print("Después de llamar a la función") return result return wrapper @simple_decorator def my_func(): print("Función principal") my_func()

Como resultado se ejecutará así:

Antes de llamar a la función
Función principal
Después de llamar a la función

La principal utilidad es la encapsulación de la lógica repetitiva fuera de la lógica comercial principal.

Detalles:

  • Sin usar functools.wraps, se pierde el nombre de la función original y su docstring.
  • Si el decorador acepta argumentos, se escribe una triple anidación de funciones.

Pregunta trampa

Pregunta: "Si decoro una función con un decorador y luego intento obtener el nombre de la función a través de __name__, ¿qué veré y cómo puedo conservar el nombre original?"

Respuesta:

Por defecto, el nombre cambiará al nombre de la envoltura (generalmente wrapper). Para conservar los metadatos originales, usa functools.wraps:

import functools def dec(f): @functools.wraps(f) def wrapper(*args): return f(*args) return wrapper @dec def foo(): pass print(foo.__name__) # imprimirá 'foo', no 'wrapper'

Ejemplos de errores reales por desconocimiento de los detalles del tema


Historia

En una gran automatización de recursos, después de envolver funciones con decoradores, el sistema de pruebas automáticas, que usaba reflexión sobre los nombres de las funciones de prueba, se rompió. El problema fue la falta de functools.wraps.


Historia

El decorador que añadía registro no soportaba funciones con diferentes firmas, ya que no se usaban *args, **kwargs. Algunas funciones simplemente fallaban en silencio.


Historia

En un proyecto con autorización en la API REST, un desarrollador implementó un decorador con parámetros, pero se olvidó de anidar correctamente las funciones (había anidación de dos niveles en lugar de tres). Como resultado, el decorador no podía aceptar parámetros.