Atualizado: 04/11/2024

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, que é o ambiente léxico para a função interna inner.

Dentro da função outer, a função interna inner acessa o ambiente léxico — a variável n —, incrementa seu valor em um, e imprime o resultado no console:

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, a variável fn recebe a função interna inner:

fn = outer()

A variável fn é um closure, ou seja, combina a função com o ambiente no qual foi criada. Mesmo que estejamos chamando a função interna fora da função externa, ela ainda lembra seu ambiente léxico e pode acessá-lo e modificá-lo, como podemos ver no resultado impresso:

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 retorna uma função que recebe um número e retorna o resultado da multiplicação.

Quando chamamos a função multiply, obtemos a função interna inner:

def inner(m): return n * m

Essa função lembra o ambiente no qual foi criada, especificamente o valor do parâmetro n. Ela também recebe o parâmetro m e retorna o produto entre n e m.

No final, ao chamar a função multiply, a variável fn recebe a função interna inner e seu ambiente léxico: o valor do parâmetro n:

fn = multiply(5)

Nesse caso, o parâmetro n é igual a 5.

Quando chamamos a função interna com o número 6:

print(fn(6))    # 30

O número 6 é passado como parâmetro m, e a função retorna o produto de n e m, ou seja, 5 * 6 = 30.

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.

Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com