Hozzáférhet-e több closure függvény ugyanahhoz a körülzárt lokális változóhoz?

A válasz igen. Már csak az a kérdés, hogy hogyan. Ez azért merül fel, mert amikor closure-ről van szó, általában egy körülzáró függvénybe ágyazott egyetlen függvényre gondolunk, ami a körülzáró függvény visszatérési értéke lesz, és ami később a hívása helyén hozzáfér a körülzáró függvény lokális változóihoz.

Azonban semmi nem korlátozza azt, hogy ne egy, hanem több beágyazott függvényt definiáljunk a körülzáró függvényen belül. Ilyen esetben a körülzáró függvény visszatérési értéke nem egyetlen függvény lesz, hanem a beágyazott függvények sorozata, ami a hívó program számára egy tuple konténerben való átadást jelent.

Ahhoz, hogy világosabb legyen, hogy miről is van szó, vegyünk egy ezt szemléltető példát! Tegyük fel, hogy egy bank számlanyilvántartását és kezelését akarjuk modellezni. Ennek keretében meg kell tudni nyitni egy számlát adott egyedi számlaszámmal, valamint be kell tudni tenni a számlára adott összeget, ki kell tudni venni róla összeget, ha az egyenleg engedi, és le is kell tudni kérni az egyenleget. Ez tehát négy művelet megvalósítását igényli: nyitás, betét, kivét és egyenleg lekérdezés.

A feladatot – mint általában – több módon is meg lehet oldani. Legtöbbször ilyenkor egy osztályt definiálnak, amelynek metódusai lesznek a nyitás, betét, kivét és egyenleg lekérdezés műveletek, a bankszámla adatokat (számlaszám és aktuális egyenleg) pedig egy megfelelő konténerre hivatkozó adatattribútum tárolja.

Mi most nem ezt tesszük, hanem a műveleteket egyetlen körülzáró függvénybe ágyazott closure függvényekkel valósítjuk meg, amelyek – mivel ugyanabban a körülzáró függvényben vannak definiálva – hozzáférnek a körülzáró függvény lokális változójaként létrehozott szótárhoz, amely a számlaszám-egyenleg értékpárokat tartalmazza.

A függvénydefiníciót és a használatot alább láthatjuk két módon is. Az első esetben a négy closure függvényt egymástól független külön változókhoz rendeljük. A másik változatban, mivel a függvények logikailag összetartoznak, egy mezőneves tuple attribútumaiként valósítjuk meg. A teszteredmények ugyanarra a bemenő adatokra természetesen mindkét esetben ugyanazok.

Vegyük észre, hogy a számlaadatokat tartalmazó szótár ebben a megoldásban teljesen biztonságban van, még véletlenül sem lehet felülírni kívülről, ami viszont elvileg nem lenne igaz, ha az egyedi osztály definíción alapuló megközelítést alkalmaztunk volna, mert mint bizonyára tudjuk, Pythonban a privátnak minősített változókhoz is hozzá lehet férni, ha ismerjük a nevüket.

Az ilyen jellegű closure megoldások mégsem annyira elterjedtek a napi gyakorlatban, aminek több oka is lehet. Egyrészt a closure működése nem mindenki számára magától értetődő, másrészt az objektumorientált paradigma és annak osztálydefiníciókon alapuló szemlélete a legelterjedtebb. Egy további indok, hogy ha nem egy-két, hanem sokkal több objektumot kell létrehozni, akkor az osztály alapú megoldás előnyösebb lehet.

E megoldás azért mutattuk be, hogy lássuk, hogy Pythonban a normál, a beágyazott és closure függvényekkel nagyon sok feladatot meg lehet oldani anélkül, hogy osztályokat kelljen definiálni. Ezért is van, hogy a Python tudásépítés lépésről lépésre című e-könyv a függvényeket, azok változatait nagyon részletesen tárgyalja, és a szokásoshoz képest – a függvényeknél szerzett ismeretekre alapozva – később veszi csak sorra az osztályok definiálásáról, valamint példányok létrehozásáról szóló tudnivalók ismertetését.

Érdekel a Python tudásépítés lépésről lépésre az alapoktól az első asztali alkalmazásig című e-könyv.