¿Qué hace def contador_llamadas?
PUNTOS CLAVE:
funcion_original=saludar()(funciones que definimos)funcion_envoltura()ejecutafuncion_original()y retorna su resultadoreturn funcion_envolturaretorna la función completa con su closureEl closure mantiene vivo el
contadorentre llamadas
EL CLOSURE ES: funcion_envoltura + contador
def contador_llamadas(funcion_original):
contador = 0 # ← Parte del closure
def funcion_envoltura(): # ← Parte del closure
nonlocal contador
contador += 1
print(f"Llamada: {contador}")
return funcion_original()
return funcion_envoltura # ← Retorna el CLOSURE completo🔍 DESGLOSE:
El CLOSURE está formado por:
funcion_envoltura- La función internacontador- La variable que recuerdafuncion_original- La función original que se decoró
🎪 ANALOGÍA:
# El CLOSURE es como un "PAQUETE" que contiene: ┌─────────────────────────┐ │ 📦 CLOSURE │ │ • funcion_envoltura │ ← El comportamiento │ • contador = 3 │ ← La memoria │ • saludar() │ ← La función original └─────────────────────────┘
🎯 RESPUESTA DIRECTA:
El closure es funcion_envoltura CON SU CAPACIDAD DE RECORDAR contador y funcion_original.
No es solo la función, ni solo la variable... es el paquete completo que mantiene vivo el entorno donde fue creado.
1. Definición del decorador:
def contador_llamadas(funcion_original):
contador = 0 # ← Esta variable "recuerda" el estado
def funcion_envoltura():
nonlocal contador # ← Permite modificar la variable exterior
contador += 1
print(f"📞 Esta es la llamada número: {contador}")
return funcion_original() # ← Ejecuta la función original
return funcion_envoltura # ← Retorna la función modificada@contador_llamadas
def saludar():#funcion_original()
print("¡Hola mundo!")¡Excelente! Ya casi lo tienes. Te lo explico super fácil:
🎯 LA CLAVE ESTÁ EN ESTA LÍNEA:
return funcion_envoltura # ← ¡NO lleva paréntesis!🔍 ¿QUÉ PASA PASO A PASO?
PASO 1: Cuando haces:
saludar_contador = contador_llamadas(saludar)contador_llamadascreacontador = 0contador_llamadasretorna la FUNCIÓNfuncion_envoltura(sin ejecutarla)saludar_contadorahora ESfuncion_envoltura
PASO 2: Cuando ejecutas:
saludar_contador()Estás ejecutando
funcion_envoltura()funcion_envolturamodificacontador(que sigue vivo)funcion_envolturaejecutasaludar()
🎪 ANALOGÍA FÁCIL:
Imagina que contador_llamadas es una fábrica de cajas mágicas:
def fabrica_cajas(funcion):
contador = 0 # ← Dentro de la fábrica
def caja_magica():
nonlocal contador
contador += 1
print(f"Usos: {contador}")
return funcion()
return caja_magica # ← Te doy la CAJA, no lo que hay dentro
# Recibo la caja mágica
mi_caja = fabrica_cajas(saludar)
# Cada vez que abro la caja:
mi_caja() # ← La caja RECUERDA cuántas veces se abrió
mi_caja() # ← Porque el contador vive DENTRO de la caja🎯 RESPUESTA DIRECTA A TU PREGUNTA:
¿Cómo guarda el valor?
Porque return funcion_envoltura retorna la FUNCIÓN COMPLETA con su "mochila" (closure) donde guarda contador.
No retorna el resultado, retorna la función que puede recordar.
# Esto:
saludar_contador = contador_llamadas(saludar)
# Es como decir:
# "saludar_contador es una función que cada vez que la llames:
# 1. Incrementará un contador que recuerda
# 2. Ejecutará saludar()
# "¡La magia está en que la función lleva consigo su memoria!
Es una función que:
Toma otra función como parámetro (
funcion_original)Crea un contador que recuerda las llamadas
Retorna una nueva función (
funcion_envoltura) que envuelve a la original
Flujo paso a paso:
1. Definición del decorador:
def contador_llamadas(funcion_original):
contador = 0 # ← Esta variable "recuerda" el estado
def funcion_envoltura():
nonlocal contador # ← Permite modificar la variable exterior
contador += 1
print(f"📞 Esta es la llamada número: {contador}")
return funcion_original() # ← Ejecuta la función original
return funcion_envoltura # ← Retorna la función modificada2. Aplicación del decorador:
@contador_llamadas
def saludar():
print("¡Hola mundo!")Esto es equivalente a:
def saludar():
print("¡Hola mundo!")
saludar = contador_llamadas(saludar) # ← ¡saludar ahora es funcion_envoltura!3. Cuando llamas saludar():
Primera llamada:
📞 Esta es la llamada número: 1
¡Hola mundo!Segunda llamada:
📞 Esta es la llamada número: 2
¡Hola mundo!El truco clave:
contador = 0solo se ejecuta UNA vez cuando se aplica el decoradorfuncion_envolturamantiene acceso acontadorgracias al closurenonlocalpermite modificar la variable del scope exterior
¿Por qué es útil?
Agrega funcionalidad sin modificar la función original
Mantiene estado entre llamadas
Reutilizable - puedes aplicarlo a cualquier función
Comentarios
Publicar un comentario