Затворања во Python

Под затворање (closure) се подразвува функција заедно со сите надворешни променливи кои и се достапни.

Во Python најчесто, кога се вели "затворање на функција", не се мисли на самата функција, туку токму на нејзините надворешни променливи.

Нека ја имаме следната функција outer, во која е декларирана променливата i и внатрешна функција inner. Во неја на i ќе се додава единица. За да променливата i коректно работи, ја додаваме инструкцијата nonlocal:

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

Сега да ја ставиме надворешната функција во променливата res и да ја повикаме со заградените загради:

pythonres = outer()
res() # ќе отпечати 1

Да ја повикаме res неколку пати. По извршувањето на кодот секој пат бројачот i ќе се зголемува за единица:

pythonres() # ќе отпечати 2
res() # ќе отпечати 3
res() # ќе отпечати 4

Сепак, овде има важна нијанса - секој повик на функцијата outer ќе го зголемува својот бројач. Да го запишеме првиот повик outer во променливата res1, а вториот повик - во променливата res2. Потоа нив последователно да ги испечатиме во конзола:

pythonres1 = outer()
res1() # ќе отпечати 1
res1() # ќе отпечати 2
res1() # ќе отпечати 3

res2 = outer()
res2() # ќе отпечати 1
res2() # ќе отпечати 2
res2() # ќе отпечати 3
Задание 1

Даден е следниот код:

pythondef outer():
  i = 10

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

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

Кажете, што ќе се отпечати во конзола.

Задание 2

Направете функција, чиј што секој повик ќе го дава следниот број на Фибоначи.

Задание 3

Направете функција, која што ќе дава случаен цел број во опсег, но така што два пати по ред да нема исти.