Cheat sheet a munka termelésének megértéséhez Python-ban

Ezt a bejegyzést a hurok tartalmazza, a népszerű kérdéseket / válaszokat a stackoverflow alapján.

Ha belülről megjelenik egy funkció a hozamkategóriában, akkor alkalmazza az alább leírt trükköt, és azonnal meg fogja érteni, hogyan működik ez a funkció.







  • 1. Először vonalat adjon hozzá a függvényhez: result = [].
  • 2. Helyezze vissza az összes hozamhívást a result.append (expr) értékkel.
  • 3. Adjon hozzá egy visszatérési eredményt a funkciódefiníció végéhez.
  • 4. Hurrá! Most nincs hozamhívás - most könnyű megérteni, hogy mi a funkció.
  • Megértették? Indítsa vissza a funkciódefiníció eredeti állapotát.

Ez a trükk segít megérteni a funkció mögött rejlő elgondolást, valamint egyértelműen ki fogja fejteni a megvalósítás logikáját. Csak egyetlen különbség van: mi történik, ha a hozamot használja, nagyon különbözik attól, ahogy a listát használja. Gyakran megközelítést generátor (hozam teszi a normális működést generátor) kevésbé lesz mohó: a memóriahasználat kevesebb és működési sebesség magasabb. És néha egy trükk bevezetheti a függvény végrehajtását egy végtelen hurokba, annak ellenére, hogy az eredeti funkció megfelelően működik. Olvassa el, hogy többet megtudjon

Megkülönböztetni az iterált objektumokat, iterátorokat és generátorokat

Először is foglalkozunk az iterátor felületével. Amikor írsz:

A Python a következő két lépést teszi:

Megnyeri az iterátor objektumot a lista jegyzékében.

A hívó iter (mylist) egy objektumot visz vissza a következő () (vagy __next __ () függvényhez a Py3-hoz).

Az eredményezett iterátort a listaelemeken keresztül hurcolja. Ezután az x-et a listán. egymás után hívja az iterátor első lépéseként kapott .next () metódust, és az érték, amelyet a .next () visszaad, hozzárendel x-hez. Ha a lista véget ér, a .next () egy StopIteration kivételt dob.

Tulajdonképpen Python csinál a fenti lépéseket minden egyes alkalommal, amikor szükség van rá, hogy át egymás után a tartalmát a tárgy: hogyan kell használni a ciklus és kód formájában therlist.extend (mylist)







Iterált tárgyak

Mi jegyzékünk egy iterábilis objektum, amely végrehajtja az iterátor protokollt. Ha a példányait meg kell ismételnie bármelyik osztályában, akkor csak be kell hajtania a __iter __ () metódust. Ennek a módszernek vissza kell adnia egy iterátort. Egy iterátor egy .ext () metódusú objektum.

A __iter __ () függvénnyel együtt definiálhatja az osztályod .next () metódust, majd __iter __ () visszaadja magát. Igaz, ez a lehetőség csak egyszerű esetekben használható. Az összetettebbeknél, ahol több iterátorra van szükség ahhoz, hogy átkerüljenek ugyanabból az objektumból, nem működik tovább.

Általában ez az iterátor protokollja. Számos Python objektum valósítja meg:

  1. Beépített listák, szótárak, sorok, készletek, fájlok
  2. Az __iter __ () metódust végrehajtó egyéni osztályok
  3. generátorok

A for loop nem tudja, melyik objektum kölcsönhatásba lép. A hurok egyszerűen követi az iterátor protokollt, és boldogan veszi az elemet az elem után minden új .next () hívással. A listák egy elem után egy elemet adnak vissza egymás után, a szótárak egymás után kiadják a kulcsokat, a fájlokat soronként. És generátorok. Hát ez a hozam.

Ha a visszatérés háromszorosát írtam vissza, akkor az f123 () az első visszatérést hívja, és a függvény befejezi a munkáját. Azonban mivel a hozamot használtuk, a függvény nem rendes és amikor a tolmács eléri a hozamot, az objektum generátorral tér vissza (a számított érték helyett), akkor a függvény felfüggesztett állapotba kerül. Ha például egy generátorobjektum átkerül a for hurokra, akkor az f123 () folytatja a munkát, a következő hozam elérésekor fut, és a következő értéket adja vissza. Ez addig történik, amíg a hurok meg nem szűnik, mert a generátor egy StopIteration kivételt dob.

Így a generátor tárgyat néz ki, mint valami adapter: egyrészt azt végrehajtja a bejáró protokoll meghatározó módszerek __iter __ () és a következő (), másrészt ellátja a funkcióját, hogy pontosan annyi, mint az előállításához szükséges a következő értéket, majd felfüggeszti azt.

Miért használja a generátorokat?

Olyan kódot írhat, amely nem generátorokat használ, de ugyanazt a logikát hajtja végre. Például a cikk kezdetén leírt ideiglenes listával a trükk használatával. Ez a trükk nem fog működni olyan esetekben, amikor végtelen hurkok vannak, túl nagy listák (ami túlzott memóriafelhasználáshoz vezet)

Egy másik megközelítés, hogy írjon néhány egyedi osztály, amely tárolja az állami hívások között azok másolatait, és értékesíti azokat .next () (vagy __next __ () in Py3) módszer. Az algoritmustól függően a .next () metóduson belüli kód nagyon összetett lehet, ami rejtett hibákat és mellékhatásokat jelent. Itt a generátorok ragyognak, egyszerű megoldást kínálva.

Olvassa el




Kapcsolódó cikkek