Closures & Captura de Escopo
Uma closure é uma função que se lembra de variáveis do escopo envolvente onde foi definida. Closures habilitam fábricas, decoradores e callbacks - mas a vinculação tardia em loops é um "pé-na-cova" clássico.
Busque em todas as páginas da documentação
Uma closure é uma função que se lembra de variáveis do escopo envolvente onde foi definida. Closures habilitam fábricas, decoradores e callbacks - mas a vinculação tardia em loops é um "pé-na-cova" clássico.
def make_multiplier(factor: int):
def multiply(value: int) -> int:
return value * factor
return multiply
double = make_multiplier(2)
print(double(10)) # 20Quando usar isso:
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)] # bug de vinculação tardia
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}: entrando")
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())O que isso demonstra:
nonlocal modifica count na função envolventei - todas veem o valor final sem o truque do argumento padrãoi=i captura o valor no momento da definição da lambdatracer retorna um decorador que fecha sobre labelnonlocal vs global - nonlocal vincula ao escopo envolvente mais próximo; global ao escopo do módulo.| Padrão | Código |
|---|---|
| Argumento padrão | lambda i=i: i |
functools.partial | partial(fn, i) |
| Função 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 cria uma variável local. Correção: nonlocal ou global explícito.__closure__ da closure quando estiver confuso.| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
functools.partial | Vinculação simples de argumento | Necessita de estado mutável nonlocal |
Classe com __call__ | Functor com estado | Closure simples de uso único |
| lambda | Lógica de uma linha minúscula | Lógica com múltiplas instruções |
Argumento padrão em def | Padrão de fábrica em loop | Já usando partial |
Função mais o ambiente capturado de variáveis livres do escopo envolvente.
Todas as closures referenciam a mesma variável i avaliada no momento da chamada - use o padrão i=i.
Para reatribuir uma variável do escopo envolvente - apenas a leitura precisa da closure sem nonlocal.
Closure captura um escopo de função envolvente específico; global refere-se a nomes no nível do módulo.
Tupla func.__closure__ de células; cell.cell_contents para depuração de valor.
Função externa recebe configuração, retorna um decorador que fecha sobre a configuração, retorna um wrapper.
Mesma armadilha de padrão de argumento mutável que funções normais - crie um novo objeto por chamada no corpo da fábrica.
Pequeno overhead em comparação com uma função simples - negligenciável para callbacks típicos.
async def aninhado fecha sobre as mesmas regras - a vinculação tardia também se aplica a lambdas assíncronas (raro).
Retorne Callable[[int], int] da fábrica para consumidores mypy.
partialVersões da Pilha: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 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+, e uv 0.6+.
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026