Coroutines är i grunden funktioner vars körning kan pausas/avbrytas vid en viss punkt, och sedan kan vi återuppta körningen från samma punkt senare när vi vill.

vi behöver en mekanism — eller för att vara mer exakt, ett nyckelord-genom vilket vi kan infoga en kontrollpunkt och berätta för programmet att vi vill pausa utförandet av funktionen här och returnera kontrollen till den punkt den ringde från. Vi återupptar avrättningen när vi vill.

i Python kan vi pausa utförandet av en funktion med hjälp av nyckelordet yield.

så här blir saker intressanta:

  • vi kan tänka på en coroutine som en funktion som har en eller flera kontrollpunkter där körningen kommer att pausas och kontrollen kommer att returneras till den punkt där den anropades från.
  • i huvudsak är en coroutine en funktion uppdelad i många delar, och vi kan utföra varje del av en coroutine när vi utför varje iteration av A för loop med funktionen next.

här är ett grundläggande exempel:

OUTPUT :<class 'generator'>
Function Starts
Function Ends

från utgången märker vi några saker:

  • först måste vi ringa coroutine/funktionen som ger oss ett generatorobjekt.
  • det generatorobjektet kommer att uppträda på samma sätt som en iterator, men i fallet med en iterator går vi över en iterabel. Med en generator kör vi delar av korutinen.
  • precis som ett StopIteration undantag kastas och fångas bakom kulisserna i A för loop, händer detsamma i det här fallet när den sista delen av coroutinen exekveras.

nu är denna paus av funktionen däremellan mycket intressant och öppnar upp några möjligheter:

  • när funktionen är pausad gör vi ingenting, vilket är fallet som vi just såg.
  • Antag att en variabel ändras flera gånger i en funktion och vi vill ha värdet på den specifika variabeln vid en viss kontrollpunkt. Sedan när vi pausar den funktionen på den specifika kontrollpunkten returnerar den värdet på den variabeln.

Låt oss se ett exempel:

OUTPUT :Function Part 1
5
Function part 2
12
Function part 3

här returneras värdet x med yield vid olika kontrollpunkter, eftersom funktionsexekveringen har pausats.

när vi kör den sista delen av funktionen och det inte finns något utbyte kvar i funktionen, efter att ha kört den sista delen, kommer ett StopIteration undantag att höjas.

ungefär som när en iterator försöker utföra nästa funktion, men det finns inga fler element kvar i iterable, det höjer också StopIteration undantag.

  • Antag att vi vill skicka ett värde (som kan vara en konstant eller variabel) vid en viss kontrollpunkt (dvs. vid ett visst tillstånd av en funktion). Vi kan också göra det med hjälp av nyckelordet yield. När vi vill skicka ett värde använder vi funktionen send istället för next.

Låt oss se ett exempel:

OUTPUT :Function part 1
6
Function part 2
12
Function part 3

anledningen till att vi använde next innan vi använde send är att vi bara kan använda send när vi är vid kontrollpunkten yield och yield finns på höger sida av uttrycket. Så för att nå den första yield måste vi använda funktionen next.

nu här kommer en intressant tillämpning av coroutines. Antag att vi vill växla fram och tillbaka mellan två funktioner som vi gör i multithreading. Vid multithreading, tills en interrupt påträffas av operativsystemet, kommer den att fortsätta att köras. I det här fallet kan vi byta när vi vill.

Låt oss se ett exempel:

OUTPUT :Function 1 part 1
Function 2 part 1
Function 1 part 2
Function 1 part 3
Function 2 part 2
Function 2 part 3
Function 2 part 4
Function 1 part 4
Function 1 part 5

i det här exemplet kan vi se att vi kan växla fram och tillbaka mellan korutiner när vi vill.

så om vi skriver vår egen anpassade schemaläggare som hanterar växlingen mellan flera koroutiner, kan vi uppnå med single threading vad vi gör med multithreading.

Coroutines har många applikationer som samtidighet och andra programmeringsmönster kan också implementeras, som producent-konsument eller avsändare-mottagare i nätverksprogrammering. Jag kommer att undersöka dem i kommande artiklar.

Coroutines är också byggstenarna i många ramar som asyncio, twisted, aiohttp. De kan också kedjas ihop för att göra rörledningar och lösa problem.