Fundamentos de los Decoradores
Los decoradores constituyen una característica fundamental en Python que posibilitan la ampliación del comportamiento de funciones sin alterar su código fuente. Un decorador no es más que una función de orden superior que recibe una función como argumento y devuelve una función modificada o una nueva función que encapsula el comportamiento original.
La sintaxis básica para implementar un decorador es la siguiente:
def decorador_base(funcion_original):
def envoltorio(*argumentos, **palabras_clave):
print("Ejecutando operaciones previas...")
resultado = funcion_original(*argumentos, **palabras_clave)
print("Ejecutando operaciones posteriores...")
return resultado
return envoltorio
Aplicación de Decoradores
Para aplicar un decorador a una función, se utiliza el símbolo @ seguido del nombre del decorador, colocándolo justo encima de la definición de la función objetivo:
@decorador_base
def funcion_ejemplo(parametro1, parametro2):
print(f"Ejecutando funcion_ejemplo con: {parametro1}, {parametro2}")
Esta sintaxis es equivalente a la asignación manual siguiente:
def funcion_ejemplo(parametro1, parametro2):
print(f"Ejecutando funcion_ejemplo con: {parametro1}, {parametro2}")
funcion_ejemplo = decorador_base(funcion_ejemplo)
Decoradores Parametrizados
Los decoradores pueden aceptar parámetros adicionales, lo que为他们提供了 mayor flexibilidad. El siguiente ejemplo implementa un decorador que ejecuta una función múltiples veces:
def ejecutar_veces(cantidad):
def decorador(funcion):
def envoltorio(*args, **kwargs):
for _ in range(cantidad):
resultado = funcion(*args, **kwargs)
return resultado
return envoltorio
return decorador
@ejecutar_veces(4)
def mostrar_saludo(nombre):
print(f"¡Saludos, {nombre}!")
mostrar_saludo("Roberto") # Imprime el saludo cuatro veces
Decoradores como Clases
También es posible crear decoradores utilizando clases que implementen el método __call__. Este método se invoca cuando la instancia de la clase se ejecuta como una función:
class GestorDecorador:
def __init__(self, funcion):
self.funcion = funcion
def __call__(self, *args, **kwargs):
print("Preparación antes de la ejecución.")
resultado = self.funcion(*args, **kwargs)
print("Cleanup después de la ejecución.")
return resultado
@GestorDecorador
def proceso_principal():
print("Cuerpo del proceso_principal.")
proceso_principal() # Imprime: Preparación, Cuerpo, Cleanup
Casos de Uso Comunes
Los decoradores encuentran aplicación en múltiples escenarios del desarrollo de software:
- Trazabilidad: Registrar información sobre invocaciones de funciones, incluyendo argumentos y resultados obtenidos.
- Medición de Rendiimento: Calcular el tiempo de ejecución de funciones críticas.
- Control de Acceso: Verificar permisos antes de permitir la ejecución de funciones sensibles.
- Optimización con Caché: Almacenar resultados previos para evitar cálculos redundantes.
- Gestión de Transacciones: Controlar recursos como conexiones a bases de datos o archivos.
Consideraciones Finales
Los decoradores representan una herramienta distintiva del ecosistema Python que facilita la extensión modular de funcionalidades. Su dominio permite construir código más limpio, reutilizable y mantenible. El conocimiento de esta técnica resulta invaluable tanto para programadores novatos como para desarrolladores experimentados que buscan patrones de diseño más sofisticados.