Pythoni sulgurid: kuidas seda kasutada ja miks?

Selles õpetuses saate teada Pythoni sulgemisest, sulgemise määratlemisest ja selle kasutamise põhjustest.

Mittelokaalne muutuja pesastatud funktsioonis

Enne sulgemisega tutvumist peame kõigepealt mõistma, mis on sisestatud funktsioon ja mittekohaline muutuja.

Teise funktsiooni sees määratletud funktsiooni nimetatakse pesastatud funktsiooniks. Pesastatud funktsioonid pääsevad juurde ümbritseva ulatuse muutujatele.

Pythonis on need mittekohalikud muutujad vaikimisi kirjutuskaitstud ja nende muutmiseks peame need deklareerima selgesõnaliselt mitte-kohalikena (kasutades mittekohalikku märksõna).

Järgnevalt on toodud näide pesastatud funktsioonist, mis pääseb juurde mittekohalikule muutujale.

 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")

Väljund

 Tere

Näeme, et pesastatud printer()funktsioon suutis pääseda ümbritseva funktsiooni mitte-lokaalsele msg-muutujale.

Sulgemisfunktsiooni määratlemine

Mis juhtuks ülaltoodud näites, kui funktsiooni viimane rida print_msg()tagastaks printer()funktsiooni selle asemel, et seda kutsuda? See tähendab, et funktsioon määratleti järgmiselt:

 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()

Väljund

 Tere

See on ebatavaline.

print_msg()Funktsiooni kutsuti string "Hello"ja tagastatakse funktsiooni pidi nime teisele. Helistades another()jäi sõnum veel meelde, kuigi olime selle print_msg()funktsiooni juba lõpetanud .

Seda tehnikat, mille abil mõned andmed ( "Helloantud juhul) koodile kinnitatakse, nimetatakse Pythonis sulgemiseks .

Seda väärtust ümbritsevas ulatuses mäletatakse isegi siis, kui muutuja väljub ulatusest või funktsioon ise eemaldatakse praegusest nimeruumist.

Väljundi nägemiseks proovige Pythoni kestas käivitada järgmine.

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

Siin töötab tagastatud funktsioon endiselt ka siis, kui algne funktsioon kustutati.

Millal meil sulgemised on?

Nagu ülaltoodud näitest nähtub, on meil Pythonis sulgemine, kui sisestatud funktsioon viitab väärtusele selle ümbritsevas ulatuses.

Kriteeriumid, millele tuleb Pythonis sulgemine luua, on kokku võetud järgmistes punktides.

  • Meil peab olema pesastatud funktsioon (funktsioon funktsiooni sees).
  • Pesastatud funktsioon peab viitama lisafunktsioonis määratletud väärtusele.
  • Lisamisfunktsioon peab tagastama pesastatud funktsiooni.

Millal sulgureid kasutada?

Milleks siis sulgemised head on?

Sulgemine võimaldab vältida globaalsete väärtuste kasutamist ja pakub mingis vormis andmete varjamist. See võib pakkuda ka probleemile objektorienteeritud lahenduse.

Kui klassis on vähe rakendatavaid meetodeid (enamasti üks meetod), võivad sulgurid pakkuda alternatiivse ja elegantsema lahenduse. Kuid kui atribuutide ja meetodite arv suureneb, on parem klass rakendada.

Siin on lihtne näide, kus sulgemine võib olla eelistatavam kui klassi määratlemine ja objektide valmistamine. Kuid eelistus on kõik teie.

 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)))

Väljund

 27 15 30

Pythoni sisekujundajad kasutavad laialdaselt ka sulgureid.

Kokkuvõtteks on hea märkida, et sulgemisfunktsiooniga kaasnevad väärtused on teada.

Kõigil funktsiooni objektidel on __closure__atribuut, mis tagastab hulga lahtrite objekte, kui see on sulgemisfunktsioon. Ülalolevale näitele viidates teame times3ja times5oleme sulgemisfunktsioonid.

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

Lahtriobjektil on atribuut cell_contents, mis salvestab suletud väärtuse.

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

Huvitavad Artiklid...