Sulkeumat Pythonissa

Sulkeumalla (closure) tarkoitetaan funktiota yhdessä kaikkien sille saatavilla olevien ulkoisten muttujien kanssa.

Pythonissa useimmiten, puhuttaessa "funktion sulkeumasta", ei tarkoiteta itse funktiota, vaan nimenomaan sen ulkoisia muuttujia.

Olkoon meillä seuraava funktio outer, jossa on määritelty muuttuja i ja sisäinen funktio inner. Siinä i:ään lisätään yksi. Jotta muuttuja i toimisi oikein, lisäämme sille nonlocal-käskyn:

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

Nyt laita ulompi funktio muuttujaan res ja kutsu sitä pyöreillä suluilla:

pythonres = outer()
res() # tulostaa 1

Kutsutaan res:ää useita kertoja. Koodin suorittamisen jälkeen laskuri i kasvaa yhdellä joka kerta:

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

Tässä on kuitenkin tärkeä vivahde - jokainen funktion outer kutsu kasvattaa omaa laskuriaan. Laitetaan ensimmäinen outer-kutsu muuttujaan res1 ja toinen kutsu - muuttujaan res2. Tulostetaan sitten ne peräkkäin konsoliin:

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

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

Annettu on seuraava koodi:

pythondef outer():
  i = 10

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

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

Mitä konsoliin tulostuu?

Задание 2

Tee funktio, jonka jokainen kutsu palauttaa seuraavan Fibonaccin luvun.

Задание 3

Tee funktio, joka antaa satunnaisen kokonaisluvun väliltä, mutta siten, että samaa lukua ei esiinny kaksi kertaa peräkkäin.