Closures - Python
Um closure representa uma função que lembra seu ambiente léxico, mesmo quando é executada fora de seu escopo original.
Tecnicamente, um closure inclui três componentes principais:
Uma função externa, que define um escopo e na qual algumas variáveis e parâmetros são definidos — este é o ambiente léxico
As variáveis e parâmetros que são definidos na função externa.
Uma função interna, que utiliza as variáveis e parâmetros da função externa.
Em Python, os closures são definidos com o uso de funções locais:
def outer(): # função externa
n = 5 # ambiente léxico — variável local
def inner(): # função interna
nonlocal n
n += 1 # operações com o ambiente léxico
print(n)
return inner
fn = outer() # fn = inner, já que a função outer retorna a função inner
# chamando a função interna inner
fn() # 6
fn() # 7
fn() # 8
Aqui, a função outer define a variável local n
inner
Dentro da função outer
inner
n
def inner(): # função interna
nonlocal n
n += 1 # operações com o ambiente léxico
print(n)
A função inner é então retornada pela função outer
return inner
Quando chamamos a função outer
fn
inner
fn = outer()
A variável fn
fn() # 6
fn() # 7
fn() # 8
Usando Parâmetros
Além das variáveis externas, os parâmetros da função também fazem parte do ambiente léxico. Vamos ver um exemplo com o uso de parâmetros:
def multiply(n):
def inner(m): return n * m
return inner
fn = multiply(5)
print(fn(6)) # 30
print(fn(7)) # 35
Aqui, a função externa multiply
Quando chamamos a função multiply
inner
def inner(m): return n * m
Essa função lembra o ambiente no qual foi criada, especificamente o valor do parâmetro n
m
n
m
No final, ao chamar a função multiply
fn
inner
n
fn = multiply(5)
Nesse caso, o parâmetro n
Quando chamamos a função interna com o número 6:
print(fn(6)) # 30
O número 6 é passado como parâmetro m
n
m
Esse código pode ser simplificado com o uso de expressões lambda:
def multiply(n): return lambda m: n * m
fn = multiply(5)
print(fn(6)) # 30
print(fn(7)) # 35
Conclusão
Os closures são uma forma eficiente de criar funções dinâmicas que "lembram" o contexto em que foram definidas, permitindo que essas funções mantenham o acesso a variáveis e parâmetros mesmo após o término da execução da função externa.