Uždarosios funkcijos Python kalboje

Uždarąja funkcija (closure) vadinama funkcija kartu su visomis jai prieinamomis išorinėmis kintamųjomis.

Python kalboje, sakant "funkcijos uždarumas", dažniausiai turimos omenyje ne pati funkcija, o būtent jos išorinės kintamosios.

Tarkime, kad turime šią funkciją outer, kurioje deklaruojama kintamoji i ir vidinė funkcija inner. Joje prie i bus pridedamas vienetas. Kad kintamoji i veiktų korektiškai, pridedame prie jos instrukciją nonlocal:

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

Dabar sudėkime išorinę funkciją į kintamąjį res ir iškvikime ją su apvaliaisiais skliaustais:

pythonres = outer()
res() # išves 1

Keliskart iškvieskime res. Po kodo vykdymo kaskart skaitiklis i bus didinamas vienetu:

pythonres() # išves 2
res() # išves 3
res() # išves 4

Tačiau čia yra svarbus niuansas – kiekvienas funkcijos outer iškvietimas didins savo skaitiklį. Pirmąjį outer iškvietimą įrašykime į kintamąjį res1, o antrąjį iškvietimą – į kintamąjį res2. Tada pačiame eiliškumame išveskime juos į konsolę:

pythonres1 = outer()
res1() # išves 1
res1() # išves 2
res1() # išves 3

res2 = outer()
res2() # išves 1
res2() # išves 2
res2() # išves 3
Задание 1

Duotas toks kodas:

pythondef outer():
  i = 10

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

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

Pasakykite, kas išves į konsolę.

Задание 2

Sukurkite funkciją, kurios kiekvienas iškvietimas grąžins sekantį Fibonačio skaičių.

Задание 3

Sukurkite funkciją, kuri generuos atsitiktinį sveikąjį skaičių intervale, bet taip, kad du kartus iš eilės nebūtų vienodų.