Cierres y Captura de Ámbito
Un cierre es una función que recuerda variables del ámbito circundante donde fue definida. Los cierres permiten fábricas, decoradores y callbacks, pero el enlace tardío en bucles es un error clásico.
Busca en todas las páginas de la documentación
Un cierre es una función que recuerda variables del ámbito circundante donde fue definida. Los cierres permiten fábricas, decoradores y callbacks, pero el enlace tardío en bucles es un error clásico.
def make_multiplier(factor: int):
def multiply(value: int) -> int:
return value * factor
return multiply
double = make_multiplier(2)
print(double(10)) # 20Cuándo usar esto:
functools.partialfrom typing import Callable
def make_counter(start: int = 0) -> Callable[[], int]:
count = start
def inc() -> int:
nonlocal count
count += 1
return count
return inc
def make_handlers_bad():
return [lambda: i for i in range(3)] # error de enlace tardío
def make_handlers_good():
return [lambda i=i: i for i in range(3)]
def tracer(label: str):
def decorate(fn):
def wrapper(*args, **kwargs):
print(f"{label}: enter")
return fn(*args, **kwargs)
return wrapper
return decorate
@tracer("api")
def ping() -> str:
return "pong"
if __name__ == "__main__":
c = make_counter(10)
print(c(), c())
print([h() for h in make_handlers_bad()])
print([h() for h in make_handlers_good()])
print(ping())Lo que esto demuestra:
nonlocal muta count en la función circundantei; todas ven el valor final sin el truco del argumento predeterminadoi=i captura el valor en el momento de la definición de la lambdatracer devuelve un decorador que cierra sobre labelnonlocal vs global - nonlocal enlaza el ámbito circundante más cercano; global el ámbito del módulo.| Patrón | Código |
|---|---|
| Argumento predeterminado | lambda i=i: i |
functools.partial | partial(fn, i) |
| Función de fábrica | def make(i): return lambda: i |
def make():
funcs = []
for i in range(3):
def f(i=i):
return i
funcs.append(f)
return funcsnonlocal crea una variable local. Corrección: nonlocal o global explícito.__closure__ del cierre cuando esté perplejo.| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
functools.partial | Vinculación simple de argumentos | Necesita estado mutable nonlocal |
Clase con __call__ | Functor con estado | Cierre simple de un solo uso |
lambda | Pequeñas líneas únicas | Lógica de múltiples sentencias |
Argumento predeterminado en def | Patrón de fábrica de bucle | Ya se usa partial |
Función más el entorno capturado de variables libres del ámbito circundante.
Todos los cierres referencian la misma variable i evaluada en el momento de la llamada; usar el predeterminado i=i.
Al reasignar una variable circundante; solo leer necesita un cierre sin nonlocal.
El cierre captura el ámbito de la función circundante específica; global nombres a nivel de módulo.
Tupla func.__closure__ de celdas; cell.cell_contents para depuración de valores.
La función externa toma la configuración, devuelve un decorador que cierra sobre la configuración, devuelve un envoltorio.
La misma trampa de valor predeterminado mutable que las funciones normales; objeto nuevo por llamada en el cuerpo de la fábrica.
Pequeña sobrecarga frente a una función normal; insignificante para callbacks típicos.
async def anidado cierra bajo las mismas reglas; el enlace tardío se aplica también a las lambdas asíncronas (raro).
Devolver Callable[[int], int] de la fábrica para consumidores de mypy.
partialVersiones de Pila: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.
Revisado por Chris St. John·Última actualización: 19 jul 2026