Closures em Python

Por closure (closure) entende-se uma função junto com todas as variáveis externas que estão acessíveis a ela.

Em Python, na maioria das vezes, ao dizer "closure de uma função", referem-se não à própria função, mas precisamente às suas variáveis externas.

Suponha que temos a seguinte função outer, na qual é declarada uma variável i e uma função interna inner. Nela, i será incrementada em um. Para que a variável i funcione corretamente, adicionamos a instrução nonlocal:

pythondef outer():
  i = 0
  def inner():
    nonlocal i
    i += 1
    print(i)
  
  return inner

Agora vamos colocar a função externa em uma variável res e chamá-la com parênteses:

pythonres = outer()
res() # exibirá 1

Vamos chamar res várias vezes. Após a execução do código, a cada vez o contador i será incrementado em um:

pythonres() # exibirá 2
res() # exibirá 3
res() # exibirá 4

No entanto, há um detalhe importante aqui - cada chamada da função outer incrementará seu próprio contador. Vamos colocar a primeira chamada de outer na variável res1, e a segunda chamada - na variável res2. Em seguida, vamos exibi-las sequencialmente no console:

pythonres1 = outer()
res1() # exibirá 1
res1() # exibirá 2
res1() # exibirá 3

res2 = outer()
res2() # exibirá 1
res2() # exibirá 2
res2() # exibirá 3
Задание 1

Dado o seguinte código:

pythondef outer():
  i = 10

  def inner():
    nonlocal i
    i -= 2
    print(i)
  return inner
  
res1 = outer()
res1()
res1()

res2 = outer()
res2()
res2()
res2()

Diga o que será exibido no console.

Задание 2

Crie uma função em que cada chamada retorne o próximo número da sequência de Fibonacci.

Задание 3

Crie uma função que retorne um número inteiro aleatório em um intervalo, mas de forma que o mesmo número não apareça duas vezes consecutivas.