Generatorer gör det enkelt att skapa iterationer i Python och i gengäld skriva mindre kod. Denna handledning kommer att presentera dig för Python-generatorer, deras fördelar och hur de fungerar.
En generator är en funktion som returnerar ett generatorobjekt som du kan ringa på Nästa()
metod, så att det för varje samtal returneras ett värde eller nästa värde. En vanlig Python-funktion använder lämna tillbaka
sökord för att returnera värden, men generatorer använder sökordet avkastning
att returnera värden. Det betyder att en Python-funktion som innehåller en avkastning
uttalandet är en generatorfunktion.
De avkastning
uttalandet stannar vanligtvis funktionen och sparar den lokala staten så att den kan återupptas direkt där den slutade. Generatorfunktioner kan ha en eller flera avkastning
uttalanden.
En generator är också en iterator, men vad är en iterator? Innan vi dyker in i detaljerna hos generatorer tycker jag att det är viktigt att veta vad iteratorer är för att de utgör en integrerad del av denna diskussion.
En Python iterator är helt enkelt en klass som definierar en __iter __ ()
metod. De flesta Python-objekt är iterbara, vilket innebär att du kan slinga över varje element i objekten. Exempel på iterables i Python inkluderar strängar, listor, tuples, ordböcker och intervaller.
Låt oss överväga exemplet nedan, där vi slingrar över en lista med färger:
färger = ["rött", "blått", "gult") def my_funct (): för färg i färger: utskrift färg
Bakom kulisserna, den för
uttalandet kommer att ringa iter ()
på listobjektet. Funktionen returnerar sedan ett iteratorobjekt som definierar metoden __Nästa__()
, som då kommer åt varje färg, en i taget. När det inte finns fler färger kvar, __Nästa__
kommer att höja en stopIteration
undantag, vilket i sin tur informerar för
loop att avsluta.
d = 'x': 10, 'y': 20, 'z': 30 för k, v i d.items (): print k, v #result # y 20 # x 10 # z 30
importera csv med öppen ('file.csv', newline = ") som fil: läsare = csv.reader (fil) för rad i läsare: utbyta rad
my_string = 'Generatorer' för sträng i my_string: skriv ut (sträng) #result # G # e # n # e # r # a # t # o # r # s
Låt oss diskutera några av fördelarna med att använda generatorer i motsats till iteratorer:
Att bygga en iterator i Python kräver att du genomför en klass med __iter __ ()
och __Nästa__()
metoder samt ta hand om eventuella fel som kan orsaka a stopIteration
fel.
klassen Reverse: "" "Iterator för looping över en sekvens bakåt." "" def __init __ (självdata): self.data = data self.index = len (data) def __iter __ (själv): returnera själv def __next __ ): om self.index == 0: höja StopIteration self.index = self.index - 1 returnera self.data [self.index]
Som du kan se ovan är genomförandet mycket långvarigt. All denna börda hanteras automatiskt av generatorer.
Generatorer hjälper till att minimera minneskonsumtionen, speciellt när det gäller stora dataset, eftersom en generator bara returnerar ett objekt i taget.
Generatorer är lat i naturen. Det innebär att de bara genererar värden när det krävs för att göra det. Till skillnad från en normal iterator, där alla värden genereras oavsett om de ska användas eller inte, genererar generatorer endast de värden som behövs. Detta leder i sin tur till att ditt program fungerar snabbare.
Att skapa en generator är väldigt lätt. Allt du behöver göra är att skriva en normal funktion, men med a avkastning
uttalande istället för a lämna tillbaka
uttalande, som visas nedan.
def gen_function (): yield "python"
Medan a lämna tillbaka
uttalandet avslutar en funktion helt, avkastning
pausar bara funktionen tills den kallas igen av Nästa()
metod.
Till exempel använder programmet nedan både av avkastning
och Nästa()
uttalanden.
def myGenerator (l): total = 1 för n i l: utbyte totalt totalt + = n newGenerator = myGenerator ([10,3]) print (nästa (newGenerator)) print (nästa (newGenerator))
Låt oss se hur generatorer fungerar. Tänk på exemplet nedan.
# generator_example.py def myGenerator (l): total = 0 för n i l: total + = n utbyte totalt newGenerator = myGenerator ([10,20,30]) print (nästa (newGenerator)) print (nästa (newGenerator)) trycket (nästa (newGenerator))
I funktionen ovan definierar vi en generator som heter myGenerator
, som tar en lista l
som ett argument. Då definierar vi en variabel total
och tilldela det ett värde på noll. Dessutom går vi igenom varje element i listan och lägger sedan till den med den totala variabeln.
Vi instanserar sedan newGenerator
och ringa till Nästa()
metod på det. Detta kommer att köra koden tills den ger det första värdet av total
, vilket kommer bli 0
I detta fall. Funktionen håller sedan värdet på den totala variabeln till nästa gång funktionen kallas. Till skillnad från en normal lämna tillbaka
uttalande, som kommer att returnera alla värden på en gång, generatorn kommer att plocka upp från var den slutade.
Nedan visas de återstående efterföljande värdena.
# generator_example.py def myGenerator (l): total = 0 för n i l: ge totalt totalt + = n newGenerator = myGenerator ([10,20,30]) skriv ut (nästa (newGenerator)) skriv ut (nästa (newGenerator)) skriv ut (nästa (newGenerator)) # resultat # 0 # 10 # 30
Om du försöker ringa funktionen efter att den har slutfört slingan får du en StopIteration
fel.
en StopIteration
höjs av Nästa()
metod för att signalera att det inte finns några ytterligare objekt som produceras av iteratorn.
0 10 30 Traceback (senaste samtal senast): Fil "python", linje 15, inStopIterationNormal funktion
I det här exemplet visar vi hur man använder flera avkastningsdeklarationer i en funktion.
# colors.py def colors (): yield "red" yield "blue" yield "green" next_color = colors () skriv ut (nästa (nästa_färg)) skriv ut (nästa (nästa_färg)) print (nästa (nästa_färg)) # resultat # röd # blå # grön
Med en normal funktion returneras alla värden när funktionen är uppkallad, en generator väntar tills Nästa()
Metoden heter igen. En gång Nästa()
kallas, färgen funktionen återupptas från var den hade stoppats.
Generatorer är mer minneseffektiva, speciellt när de arbetar med mycket stora listor eller stora objekt. Detta beror på att du kan använda utbyten för att arbeta på mindre bitar istället för att ha hela data i minnet på en gång.
Dessutom glöm inte att se vad vi har tillgång till för försäljning och för studier på Envato Market, och tveka inte att ställa några frågor och ge din värdefulla feedback genom att använda foderet nedan.
Dessutom, om du känner dig fast, finns det en mycket bra kurs på Python generatorer i kursavsnittet.