Domknięcia w Pythonie

Przez domknięcie (closure) rozumie się funkcję wraz ze wszystkimi zewnętrznymi zmiennymi, które są dla niej dostępne.

W Pythonie, mówiąc "domknięcie funkcji", częściej ma się na myśli nie samą tę funkcję, a właśnie jej zewnętrzne zmienne.

Załóżmy, że mamy następującą funkcję outer, w której zadeklarowana jest zmienna i i funkcja wewnętrzna inner. W niej do i będzie dodawana jedynka. Aby zmienna i działała poprawnie, dodajemy do niej instrukcję nonlocal:

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

Teraz przypiszmy funkcję zewnętrzną do zmiennej res i wywołajmy ją z nawiasami okrągłymi:

pythonres = outer()
res() # wypisze 1

Wywołajmy res kilka razy. Po wykonaniu kodu za każdym razem licznik i będzie zwiększany o jeden:

pythonres() # wypisze 2
res() # wypisze 3
res() # wypisze 4

Jednakże jest tu ważny niuans - każde wywołanie funkcji outer będzie zwiększać swój własny licznik. Przypiszmy pierwsze wywołanie outer do zmiennej res1, a drugie wywołanie - do zmiennej res2. Następnie wypiszmy je kolejno w konsoli:

pythonres1 = outer()
res1() # wypisze 1
res1() # wypisze 2
res1() # wypisze 3

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

Dany jest następujący kod:

pythondef outer():
  i = 10

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

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

Powiedz, co zostanie wypisane w konsoli.

Задание 2

Stwórz funkcję, której każde wywołanie będzie zwracać kolejną liczbę Fibonacciego.

Задание 3

Stwórz funkcję, która będzie zwracać losową liczbę całkowitą z przedziału, ale tak, aby dwa razy z rzędu nie była taka sama.