MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Închideri

O închidere (closure) reprezintă o funcție care își amintește mediul său lexical chiar și atunci când este executată în afara domeniului său de vizibilitate.

Tehnic, o închidere include trei componente:

  • Funcția exterioară, care definește un anumit domeniu de vizibilitate și în care sunt definite unele variabile și parametri - mediul lexical.
  • Variabilele și parametrii (mediul lexical) care sunt definite în funcția exterioară.
  • Funcția imbricată, care folosește variabilele și parametrii funcției exterioare.

Pentru a defini închideri în Python, se folosesc funcții locale:

def outer():        # funcție exterioară
   n = 5           # mediu lexical - variabilă locală
   def inner():    # funcție locală
       nonlocal n
       n += 1      # operații cu mediul lexical
       print(n)
   return inner
fn = outer()   # fn = inner, deoarece funcția outer returnează funcția inner
# apelăm funcția internă inner
fn()    # 6
fn()    # 7
fn()    # 8

Aici, funcția outer definește o variabilă locală n - acesta este mediul lexical pentru funcția internă:

În interiorul funcției outer, este definită funcția internă inner, care accesează mediul său lexical - variabila n, îi crește valoarea cu unul și o afișează pe consolă:

def inner():    # funcție locală
   nonlocal n
   n += 1      # operații cu mediul lexical
   print(n)

Această funcție locală este returnată de funcția outer:

return inner

În program, apelăm funcția outer și obținem în variabila fn funcția locală inner:

fn = outer()

Variabila fn reprezintă o închidere, adică combină două lucruri: funcția și mediul în care funcția a fost creată. Și, deși am obținut funcția locală și o putem apela în afara funcției înconjurătoare în care a fost definită, ea își amintește mediul său lexical și poate să-l acceseze și să-l modifice, așa cum vedem în ieșirea consolei:

fn()    # 6
fn()    # 7
fn()    # 8

Utilizarea parametrilor

Pe lângă variabilele exterioare, mediul lexical include și parametrii funcției înconjurătoare. Să analizăm utilizarea parametrilor:

def multiply(n):
   def inner(m): return n * m
   return inner
fn = multiply(5)
print(fn(5))        # 25
print(fn(6))        # 30
print(fn(7))        # 35


Aici, funcția exterioară - multiply returnează o funcție care primește un număr și returnează un număr.

Apelul funcției multiply() returnează funcția locală inner:

def inner(m): return n * m

Această funcție își amintește mediul în care a fost creată, în special valoarea parametrului n. În plus, primește și un parametru și returnează produsul parametrilor n și m.

În final, la apelul funcției multiply, este definită variabila fn, care primește funcția locală inner și mediul său lexical - valoarea parametrului n:

fn = multiply(5)

În acest caz, parametrul n este egal cu 5.

La apelul funcției locale, de exemplu, în cazul:

print(fn(6))        # 30

Numărul 6 este transmis ca parametru m funcției locale, care returnează produsul n și m, adică 5 * 6 = 30.

De asemenea, am putea scurta acest cod folosind lambda:

def multiply(n): return lambda m: n * m
fn = multiply(5)
print(fn(5))        # 25
print(fn(6))        # 30
print(fn(7))        # 35
← Lecția anterioară Lecția următoare →