Comprender los Decoradores en Python
Los decoradores en Python son una forma poderosa y flexible de modificar el comportamiento de una función o una clase. Son una forma de funciones de orden superior, lo que significa que pueden tomar una función como argumento, agregarle alguna funcionalidad y luego devolver una nueva función. Esto le permite extender la funcionalidad de una función sin modificar su lógica central.
¿Qué son los Decoradores?
Los decoradores son una forma de envolver una función con otra función. La función interna, conocida como el "decorador", generalmente realiza algún procesamiento o funcionalidad adicional antes o después de que se llame a la función original. Esto puede ser útil para tareas como el registro (logging), el almacenamiento en caché (caching), la autenticación y más.
Cómo Funcionan los Decoradores
Los decoradores en Python se definen utilizando el símbolo @, seguido del nombre de la función decoradora, colocado justo antes de la definición de la función. Cuando una función está decorada, se llama a la función decoradora con la función original como argumento, y el resultado de la función decoradora se utiliza como la nueva función.
A continuación, un ejemplo sencillo de un decorador que registra los argumentos pasados a una función:
def log_args(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with args={args} and kwargs={kwargs}")
return func(*args, **kwargs)
return wrapper
@log_args
def add_numbers(a, b):
return a + b
result = add_numbers(2, 3)
print(result)
Esto producirá la siguiente salida:
Calling add_numbers with args=(2, 3) and kwargs={}
5
Composición de Decoradores
Los decoradores se pueden componer, lo que le permite aplicar múltiples decoradores a una sola función. Los decoradores se aplican de abajo hacia arriba, siendo el decorador más interno el primero en aplicarse.
def uppercase(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result.upper()
return wrapper
@uppercase
@log_args
def greet(name):
return f"Hello, {name}!"
print(greet("LabEx"))
Esto producirá la siguiente salida:
Calling greet with args=('LabEx',) and kwargs={}
HELLO, LABEX!
Comprender la Sintaxis *args y **kwargs
La sintaxis *args y **kwargs se utiliza en los decoradores para permitir que el decorador maneje funciones con cualquier número de argumentos posicionales y de palabra clave. *args recopila todos los argumentos posicionales en una tupla, mientras que **kwargs recopila todos los argumentos de palabra clave en un diccionario.
Esta flexibilidad asegura que el decorador se pueda aplicar a una amplia gama de funciones, independientemente de sus firmas de argumentos.