Python slēgšana: kā to izmantot un kāpēc?

Šajā apmācībā jūs uzzināsiet par Python slēgšanu, kā definēt slēgšanu un iemeslus, kādēļ tā jāizmanto.

Lokālais mainīgais ligzdotā funkcijā

Pirms nonākam pie tā, kas ir slēgšana, mums vispirms ir jāsaprot, kas ir ligzdotā funkcija un lokālais mainīgais.

Funkciju, kas definēta citas funkcijas iekšienē, sauc par ligzdotu funkciju. Ligzdotās funkcijas var piekļūt norobežojošās darbības jomas mainīgajiem.

Programmā Python šie lokālie mainīgie pēc noklusējuma ir tikai lasāmi, un, lai tos modificētu, mums tie skaidri jāpaziņo par vietējiem (izmantojot lokālo atslēgvārdu).

Šis ir piemērs ligzdotajai funkcijai, kas piekļūst mainīgajam, kas nav lokāls.

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

Rezultāts

 Sveiki

Mēs varam redzēt, ka ligzdotā printer()funkcija varēja piekļūt norobežojošās funkcijas lokālajam msg mainīgajam.

Slēgšanas funkcijas noteikšana

Kas notiktu iepriekšējā piemērā, ja funkcijas pēdējā rinda print_msg()atgrieztu printer()funkciju, nevis to izsauktu? Tas nozīmē, ka funkcija tika definēta šādi:

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

Rezultāts

 Sveiki

Tas ir neparasti.

print_msg()Funkcija sauca ar virknes "Hello"un atgriezās funkcija saistīta ar vārda citu. Zvanot another(), ziņa joprojām tika atcerēta, lai gan mēs jau bijām beiguši izpildīt print_msg()funkciju.

Šo paņēmienu, ar kuru daži dati ( "Hellošajā gadījumā) tiek piesaistīti kodam , Python sauc par slēgšanu .

Šī vērtība aptverošajā darbības sfērā tiek saglabāta pat tad, kad mainīgais iziet no darbības jomas vai pati funkcija tiek noņemta no pašreizējās vārdu vietas.

Mēģiniet palaist šo Python čaulā, lai redzētu izvadi.

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

Šeit atgrieztā funkcija joprojām darbojas pat tad, ja sākotnējā funkcija tika izdzēsta.

Kad mums ir slēgšana?

Kā redzams no iepriekš minētā piemēra, mums Python ir slēgšana, kad ligzdotā funkcija atsaucas uz vērtību tā aptverošajā darbības jomā.

Kritēriji, kas jāievēro, lai izveidotu slēgšanu Python, ir apkopoti šādos punktos.

  • Mums ir jābūt ligzdotai funkcijai (funkcija funkcijas iekšpusē).
  • Ligzdotajai funkcijai ir jāatsaucas uz vērtību, kas definēta pievienojošajā funkcijā.
  • Apvalka funkcijai jāatgriež ligzdotā funkcija.

Kad izmantot slēgšanas ierīces?

Tātad, kam slēgšana ir laba?

Aizvēršana var izvairīties no globālo vērtību izmantošanas un nodrošina sava veida datu slēpšanu. Tas var arī nodrošināt objektorientētu problēmas risinājumu.

Ja klasē ir maz metožu (viena metode lielākoties), slēgšana var nodrošināt alternatīvu un elegantāku risinājumu. Bet, kad atribūtu un metožu skaits kļūst lielāks, labāk ir ieviest klasi.

Šeit ir vienkāršs piemērs, kur slēgšana varētu būt vēlamāka nekā klases noteikšana un objektu izgatavošana. Bet priekšroka ir tikai jums.

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

Rezultāts

 27 15 30

Python dekoratori plaši izmanto arī aizdares.

Noslēgumā ir labi norādīt, ka var uzzināt vērtības, kas iekļaujas slēgšanas funkcijā.

Visiem funkciju objektiem ir __closure__atribūts, kas atgriež šūnu objektu kopu, ja tā ir slēgšanas funkcija. Atsaucoties uz iepriekš minēto piemēru, mēs zinām times3un times5esam slēgšanas funkcijas.

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

Šūnas objektam ir atribūts cell_contents, kas saglabā slēgto vērtību.

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

Interesanti raksti...