Python Brainstorms 2 - Closures em Python, um pequeno exemplo

Há alguns dias me foi questionado sobre como funcionam closures em python.

Para o entendimento geral eu recomendo uma leitura neste post do Walter.

CORRIGIDO:

O Adam Victor me atentou para o meu exemplo, pois poderia ser feito usando globals.

Aproveitei para corrigir o código já mostrando o impacto do uso de globals quando usa-se precisa de nested scopes.

Exemplo anterior, perfeitamente possível de refazer usando globals:

[python]

variavel = 25
closure = [25]
def incrementar_variavel():
try:
variavel +=12
except UnboundLocalError:
#A variavel nao definida no escopo atual
pass

def incrementar_closure():
closure[0] +=12

print “Variavel: “, variavel
print “Closure: “, closure[0]
incrementar_closure()
incrementar_variavel()
print “Variavel: “, variavel
print “Closure: “, closure[0]
[/python]

Agora o exemplo 2, mostrando o impacto do uso de globals.

[python]

def incrementar_variavel():
variavel = 25
def incrementa():
try:
variavel +=12
return variavel
except UnboundLocalError:
return ‘A variavel nao definida no escopo atual’
pass
return incrementa

def incrementar_closure():
closure = [25]
def incrementa():
closure[0] +=12
return closure[0]
return incrementa

def incrementar_global1():
closure = 25
def incrementa():
global closure
closure +=12
return closure
return incrementa

def incrementar_global2():
global closure
closure = 25
def incrementa():
global closure
closure +=12
return closure
return incrementa

variavel = incrementar_variavel()
closure = incrementar_closure()

print variavel()
print closure()

#vejamos o estrago de globals usando quando necessitamos de nested scopes

#estrago um - como global a funcao ja definida com o nome de closure recebera uma tentativa de incremental add
com_global1 = incrementar_global1()
try:
print com_global1()
except TypeError:
print “Veja aqui que sera tentado incrementar uma funcao. Este eh o estrago numero 1 :)”
print closure()
#estrago dois - a funcao definida com o nome: closure acima, simplesmente sera sobreposta com o valor 25
com_global2 = incrementar_global2()
print com_global2()

print closure # opa agora closure nao eh mais uma funcao, logo, nao eh mais “callable”

[/python]

Basicamente é o seguinte, python 2.4 e 2.5 necessitam desse pequeno truque usando lista como uma forma de ter uma variavel com escopo abrangente.

Baixe o source aqui do exemplo 1 aqui

O exemplo 2 está aqui!

One Response to “Python Brainstorms 2 - Closures em Python, um pequeno exemplo”

  1. Adam Victor Nazareth Brandizzi Says:

    Não precisa não! É só declarar “variavel” como global!

    variavel = 25
    def incrementar_variavel():
    global variavel
    try:
    variavel +=12
    except UnboundLocalError:
    #A variavel nao definida no escopo atual
    pass

    Ademais, acredito que isto não seja closure, não… Até onde eu saiba, closure (ou fechamento) é o processo de uma função armazenar os valores das variáveis locais da função onde é declarada. Dê uma olhada em http://en.wikipedia.org/wiki/Closure_%28computer_science%29

Leave a Reply