Cómo crear y utilizar decoradores en Python
Aprenda a escribir y aplicar decoradores en Python. Domine las funciones de ajuste, modifique el comportamiento, maneje argumentos y preserve metadatos con ajustes.
Descripción general
Los decoradores son una de las características de sintaxis más elegantes y poderosas de Python, que le permiten modificar el comportamiento de una función o clase sin cambiar permanentemente su código. Se utilizan ampliamente para cuestiones transversales como registrar tiempos de ejecución, hacer cumplir la autenticación de usuarios, almacenar en caché los resultados (memorización) y auditar los puntos finales de API.
En esencia, un decorador es una función de orden superior que toma otra función como argumento, define una función contenedora anidada que inyecta cierta lógica personalizada y devuelve esta función contenedora. Python proporciona una sintaxis taquigráfica limpia utilizando el símbolo `@` para aplicar decoradores a funciones, haciéndolas visualmente elegantes.
Al escribir decoradores, normalmente querrá que la función decorada admita cualquier número de argumentos posicionales y de palabras clave. Puede lograr esto diseñando la función contenedora anidada para aceptar `*args` y `**kwargs` y pasarlos a la función de destino. Además, debe usar `functools.wraps` en la función contenedora para preservar la cadena de documentación y los metadatos del nombre de la función original.
Código y salida de ejecución
Este script demuestra cómo escribir un decorador de registro y ajustar una función para inspeccionar entradas, salidas y metadatos.
from functools import wraps
# 1. Defining a decorator
def log_execution(func):
@wraps(func) # Preserves original function metadata
def wrapper(*args, **kwargs):
print(f"[Log] Calling function: {func.__name__} with args: {args}")
result = func(*args, **kwargs)
print(f"[Log] Finished {func.__name__}. Result: {result}")
return result
return wrapper
# 2. Applying the decorator using @ syntax
@log_execution
def add_numbers(a, b):
"""Adds two numbers and returns the sum."""
return a + b
# 3. Invoking the decorated function
sum_result = add_numbers(15, 25)
print("Sum Result:", sum_result)
# Verifying metadata preservation
print("Docstring preserved:", add_numbers.__doc__)[Log] Calling function: add_numbers with args: (15, 25)
[Log] Finished add_numbers. Result: 40
Sum Result: 40
Docstring preserved: Adds two numbers and returns the sum.Implementación paso a paso
- Defina una función decoradora externa que tome la función de destino como argumento.
- Importe y aplique @functools.wraps(func) en su función contenedora anidada para proteger los metadatos originales.
- Implemente wrapper(*args, **kwargs) para capturar variables de entrada, inyectar lógica e invocar la función de destino.
- Devuelve el objeto de función contenedora del bloque de encabezado decorador.
- Aplique el decorador usando @decorator_name directamente encima de la firma de la función de destino.
Preguntas frecuentes
¿Por qué es necesario @functools.wraps dentro de los decoradores?
Sin envolturas, la función decorada pierde su identidad original (sus atributos __name__ y __doc__ son reemplazados por los de la función contenedora anidada), lo que dificulta la depuración y la introspección del código.
¿Puedo aplicar varios decoradores a una sola función?
¡Sí! Puede encadenar decoradores apilando varias líneas @. Python los aplica de abajo hacia arriba (la definición de función más cercana se ejecuta primero).
Temas relacionados
Domina *args y **kwargs en Python. Aprenda a escribir funciones flexibles con argumentos dinámicos posicionales y de palabras clave, descomprimir colecciones y crear funciones contenedoras.
Cómo utilizar funciones Lambda en PythonAprenda a utilizar funciones lambda en Python. Domine funciones anónimas, devoluciones de llamadas en línea y clasificación de datos de listas con claves lambda.
Recursos recomendados de Python
Amplíe sus conocimientos con tutoriales interactivos relacionados, hojas de trucos y comparaciones de códigos.
Variables de Python y tipos de datos explicados
Comprender las variables de Python y los tipos de datos principales (cadenas, enteros, flotantes, booleanos). Una guía completa para principiantes sobre la asignación de memoria en Python.
Hoja de referencia de métodos del diccionario Python
Aprenda los métodos del diccionario de Python. Guía de referencia completa para inserciones, recuperaciones, actualizaciones y comprobaciones de pares clave-valor.
Python vs JavaScript: ¿Qué lenguaje de programación es mejor?
Una comparación completa entre Python y JavaScript. Explore las diferencias de sintaxis, el rendimiento, los casos de uso (backend frente a frontend) y ejemplos de codificación.