Затварања у Пајтону

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

У Пајтону најчешће, када се каже "затварање функције", не мисли се на саму ту функцију, већ управо на њене спољашње променљиве.

Нека имамо следећу функцију 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

Направите функцију, која ће давати случајан цео број у интервалу, али тако да се не понови исти број два пута узастопно.