Python bezárások: Hogyan kell használni és miért?

Ebben az oktatóanyagban megismerheti a Python bezárását, a bezárás definiálását és a használatának okait.

Nem lokális változó beágyazott függvényben

Mielőtt rátérnénk arra, hogy mi a bezárás, először meg kell értenünk, mi a beágyazott függvény és nem lokális változó.

Egy másik függvényben definiált függvényt beágyazott függvénynek nevezünk. A beágyazott függvények elérhetik a csatoló hatókör változóit.

A Pythonban ezek a nem lokális változók alapértelmezés szerint csak olvashatóak, és módosításukhoz kifejezetten nem helyi (nem helyi kulcsszót használva) deklarálnunk kell.

Az alábbiakban bemutatunk egy példát egy beágyazott függvényhez, amely nem helyi változóhoz fér hozzá.

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

Kimenet

 Szia

Láthatjuk, hogy a beágyazott printer()függvény elérhette a bezáró függvény nem helyi msg változóját.

Zárási funkció meghatározása

A fenti példában mi történne, ha a függvény utolsó sora print_msg()visszaadná a printer()függvényt ahelyett, hogy meghívná? Ez azt jelenti, hogy a függvényt a következőképpen definiálták:

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

Kimenet

 Szia

Ez szokatlan.

A print_msg()függvényt a karakterlánccal hívtuk meg, "Hello"és a visszaküldött függvényt egy másik névhez kötöttük. Híváskor another()az üzenet még mindig emlékezett, bár már befejeztük a print_msg()funkció végrehajtását .

Ezt a technikát, amellyel egyes adatok ( "Helloebben az esetben) csatolódnak a kódhoz, a Python bezárásnak nevezzük .

Ez az érték a záró hatókörben akkor is megmarad, ha a változó kilép a hatókörből, vagy maga a függvény eltávolításra kerül az aktuális névtérből.

A kimenet megtekintéséhez próbálkozzon a következők futtatásával a Python héjban.

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

Itt a visszaküldött függvény akkor is működik, ha az eredeti függvényt törölték.

Mikor lesznek bezárásaink?

A fenti példából látható, hogy van egy bezárásunk a Pythonban, amikor egy beágyazott függvény egy értékre hivatkozik a befogadó hatókörében.

A Python bezárásának létrehozásához teljesítendő kritériumokat a következő pontok foglalják össze.

  • Be kell ágyazott függvényünk (függvény egy függvényen belül).
  • A beágyazott függvénynek a becsatoló függvényben meghatározott értékre kell utalnia.
  • A csatoló függvénynek vissza kell adnia a beágyazott függvényt.

Mikor kell használni a zárókat?

Tehát mire jóak a lezárások?

A bezárásokkal elkerülhető a globális értékek használata, és az adatok elrejtésének valamilyen formája van. Objektumorientált megoldást is kínálhat a problémára.

Ha kevés módszer (a legtöbb esetben egy módszer) van megvalósítva egy osztályban, akkor a lezárások alternatív és elegánsabb megoldást nyújthatnak. De amikor az attribútumok és a módszerek száma nagyobb lesz, jobb egy osztályt megvalósítani.

Itt van egy egyszerű példa, ahol a lezárás előnyösebb lehet, mint egy osztály meghatározása és objektumok készítése. De a preferencia csak a tiéd.

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

Kimenet

 27 15 30

A Python dekorátorok széleskörűen használják a zárókat is.

Befejezésül jó megjegyezni, hogy a zárási függvénybe beillesztett értékeket meg lehet tudni.

Minden függvényobjektum rendelkezik egy __closure__attribútummal, amely egy sor cellatárgyat ad vissza, ha ez egy zárási függvény. A fenti példára hivatkozva ismerjük a zárási funkciókat times3és times5azok vagyunk.

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

A cellaobjektum rendelkezik a cellatartalom attribútummal, amely a zárt értéket tárolja.

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

érdekes cikkek...