Python Closures: Kuinka sitä käytetään ja miksi?

Tässä opetusohjelmassa opit Python-sulkemisesta, kuinka määritellä sulkeminen ja syyt sinun pitäisi käyttää sitä.

Paikallinen muuttuja sisäkkäisessä funktiossa

Ennen kuin aloitamme sulkemisen, meidän on ensin ymmärrettävä, mikä sisäkkäinen funktio ja ei-paikallinen muuttuja on.

Toisen funktion sisällä määriteltyä toimintoa kutsutaan sisäkkäin. Sisäkkäiset funktiot voivat käyttää suljetun laajuuden muuttujia.

Pythonissa nämä ei-paikalliset muuttujat ovat oletusarvoisesti vain luku -ominaisuuksia, ja niiden muuttamiseksi meidän on ilmoitettava ne nimenomaisesti ei-paikallisiksi (käyttäen ei-paikallista avainsanaa).

Seuraava on esimerkki sisäkkäisestä toiminnosta, joka käyttää ei-paikallista muuttujaa.

 def print_msg(msg): # This is the outer enclosing function def printer(): # This is the nested function print(msg) printer() # We execute the function # Output: Hello print_msg("Hello")

Tuotos

 Hei

Voimme nähdä, että sisäkkäinen printer()funktio pystyi käyttämään sulkevan funktion ei-paikallista msg-muuttujaa.

Sulkutoiminnon määrittäminen

Mitä tapahtuisi yllä olevassa esimerkissä, jos funktion viimeinen rivi print_msg()palauttaisi printer()funktion kutsumisen sijaan? Tämä tarkoittaa, että toiminto määritettiin seuraavasti:

 def print_msg(msg): # This is the outer enclosing function def printer(): # This is the nested function print(msg) return printer # returns the nested function # Now let's try calling this function. # Output: Hello another = print_msg("Hello") another()

Tuotos

 Hei

Se on epätavallista.

print_msg()Funktiota kutsuttiin merkkijono "Hello"ja palautetaan funktion sitoutui nimen toiselle. Soittamisen another()yhteydessä viesti muistettiin edelleen, vaikka olimme jo suorittaneet print_msg()toiminnon.

Tätä tekniikkaa, jolla jotkut tiedot ( "Hellotässä tapauksessa) liitetään koodiin, kutsutaan sulkemiseksi Pythonissa .

Tämä arvo sulkeutuvassa laajuudessa muistetaan, vaikka muuttuja menee alueen ulkopuolelle tai toiminto itse poistetaan nykyisestä nimiavaruudesta.

Yritä suorittaa seuraava Python-kuoressa nähdäksesi tulosteen.

 >>> del print_msg >>> another() Hello >>> print_msg("Hello") Traceback (most recent call last):… NameError: name 'print_msg' is not defined

Tässä palautettu toiminto toimii edelleen, vaikka alkuperäinen toiminto poistettaisiin.

Milloin meillä on sulkemisia?

Kuten yllä olevasta esimerkistä nähdään, meillä on suljettu Pythonissa, kun sisäkkäinen funktio viittaa arvoon sen sulkeutuvassa laajuudessa.

Kriteerit, jotka on täytettävä sulkemisen luomiseksi Pythonissa, on koottu seuraaviin kohtiin.

  • Meillä on oltava sisäkkäinen funktio (funktio funktion sisällä).
  • Sisäkkäisen funktion on viitattava oheisessa funktiossa määritettyyn arvoon.
  • Kotelointitoiminnon on palautettava sisäkkäinen toiminto.

Milloin sulkimia käytetään?

Joten mihin sulkemiset ovat hyviä?

Sulkemisilla voidaan välttää globaalien arvojen käyttö ja tarjota jonkinlainen tietojen piilottaminen. Se voi myös tarjota ongelmaan kohdennetun ratkaisun.

Kun luokassa on muutama menetelmä (useimmissa tapauksissa yksi menetelmä), sulkemiset voivat tarjota vaihtoehtoisen ja tyylikkäämmän ratkaisun. Mutta kun määritteiden ja menetelmien määrä kasvaa, on parempi toteuttaa luokka.

Tässä on yksinkertainen esimerkki, jossa sulkeminen voi olla parempi kuin luokan määritteleminen ja esineiden tekeminen. Mutta etusija on sinun.

 def make_multiplier_of(n): def multiplier(x): return x * n return multiplier # Multiplier of 3 times3 = make_multiplier_of(3) # Multiplier of 5 times5 = make_multiplier_of(5) # Output: 27 print(times3(9)) # Output: 15 print(times5(3)) # Output: 30 print(times5(times3(2)))

Tuotos

 27 15 30

Python Decorators käyttää laajasti myös sulkimia.

Loppuhuomautuksena on hyvä huomauttaa, että arvot, jotka sulkeutuvat sulkutoimintoon, voidaan selvittää.

Kaikilla funktio-objekteilla on __closure__attribuutti, joka palauttaa joukon soluobjekteja, jos se on sulkutoiminto. Viitaten yllä olevaan esimerkkiin tiedämme times3ja times5olemme sulkemistoimintoja.

 >>> make_multiplier_of.__closure__ >>> times3.__closure__ (,)

Soluobjektilla on attribuutti cell_contents, joka tallentaa suljetun arvon.

 >>> times3.__closure__(0).cell_contents 3 >>> times5.__closure__(0).cell_contents 5

Mielenkiintoisia artikkeleita...