Resultaten van onafhankelijke coroutines in de invoervolgorde verzamelen.
Een verzameling resultaten verder verwerken zonder bronnen opnieuw aan te roepen.
Gewone fouten bewust laten doorgaan of als afzonderlijke resultaten behandelen.
Een dagrapport vraagt drie onafhankelijke aantallen op. De snelste bron hoort niet automatisch in de eerste kolom van het rapport: die kolom heeft al een betekenis. Je wilt het werk laten overlappen en toch kunnen vertrouwen op de koppeling tussen elke bron en haar resultaat.
Eén await voor meerdere bewerkingen
Met asyncio.gather wacht je op meerdere awaitables tegelijk. Je geeft de coroutineobjecten als afzonderlijke argumenten mee. Gather plant coroutines als taken en geeft bij een succesvolle uitvoering een lijst met hun resultaten terug.
Die lijst volgt de volgorde van de argumenten. De eerste bron kan als laatste klaar zijn en toch het eerste resultaat leveren. De volgorde van klaar zijn is dus iets anders dan de volgorde waarin je de resultaten later gebruikt.
Het voorbeeld vraagt informatie voor twee vaste kolommen op. De getallen hoeven niet op dezelfde manier berekend te worden om ze samen te kunnen afwachten. Je kunt aan de twee posities zien bij welke aanroep elk getal hoort.
Heb je een lijst coroutineobjecten, dan gebruik je asyncio.gather(*pending). De ster pakt de lijst uit tot losse argumenten. In deze oefeningen krijg je juist een lijst async functies: maak daar eerst de coroutineobjecten van met job() voor iedere functie.
Eén uitvoering, meerdere gebruiksmogelijkheden
Na het verzamelen heb je gewone waarden. Je kunt ze optellen, aan een naam koppelen of later nogmaals bekijken zonder de bronnen opnieuw uit te voeren. Voor een lege lijst bronnen is de verzamelde lijst leeg en de som van die waarden nul.
Roep de functies precies eenmaal aan. job() een keer voor de som en daarna nog eens voor de weergave maakt twee uitvoeringen. Dat kan meer werk veroorzaken of zelfs een ander antwoord opleveren wanneer een bron intussen verandert.
Gewone fouten laten doorgaan
Standaard geeft gather de eerste gewone uitzondering door aan de coroutine die erop wacht. Dat is nuttig wanneer het complete rapport zonder één van de bronnen geen betekenis heeft. Een fout vervangen door nul kan dan een overtuigend maar onjuist totaal opleveren.
Een andere belangrijke eigenschap: het doorgaan van die fout annuleert de andere bewerkingen niet automatisch. Zij kunnen nog lopen wanneer de aanroeper de fout ontvangt. De code die het werk beheert blijft verantwoordelijk voor wat er daarna met dat werk gebeurt.
In deze les laat de oefenomgeving die andere bron gecontroleerd afronden. In de volgende les onderzoek je TaskGroup, waarmee de levensduur van verwant werk anders wordt geregeld. Gather en TaskGroup zijn daarom geen uitwisselbare spellingen van hetzelfde foutbeleid.
Fouten als deelresultaat
Met return_exceptions=True wacht gather ook bij gewone fouten op de andere bewerkingen. Op de plaats van een mislukte bewerking staat dan het exceptionobject. Dat object is geen geslaagd antwoord: de aanroeper moet het bewust herkennen en verwerken.
Het voorbeeld maakt zichtbaar welke bron bruikbaar is en welke fout ging. Deze oefening gebruikt gewone exceptions, zoals ValueError. Annulering heeft een eigen betekenis en volgt in een latere les.
Veelgemaakte fout: een foutobject als waarde gebruiken
Wie alle antwoorden zonder controle optelt, kan proberen een getal bij een exceptionobject op te tellen. Het gevolg is een nieuwe fout die het oorspronkelijke probleem onduidelijk maakt. Controleer daarom eerst of een uitkomst een Exception is wanneer je voor foutresultaten hebt gekozen.
De opdrachten houden beide beleidskeuzes apart. Een strikte functie geeft de oorspronkelijke fout door; de functie voor deelresultaten maakt juist expliciete tuples met "ok" of "error". Bewaar daarbij de foutklasse en melding, zodat de lezer begrijpt waarom een onderdeel ontbreekt.
AAN DE SLAG 0/4
1
De invoervolgorde bewaren
Maak async values(jobs). De lijst bevat async functies zonder argumenten. Voer iedere bron eenmaal uit, laat onafhankelijke bronnen samen beginnen en geef een lijst resultaten terug in de invoervolgorde. Een lege bronnenlijst geeft [].
2
Een verzameld totaal
Maak async total(jobs). Verzamel de gehele waarden van de onafhankelijke async bronnen, elk eenmaal uitgevoerd, en geef hun som terug. Een lege bronnenlijst heeft totaal nul.
3
Deelresultaten labelen
Maak async tagged_results(jobs). Wacht op alle bronnen met return_exceptions=True. Geef per uitkomst in invoervolgorde een tuple ("ok", waarde) of bij een gewone Exception ("error", klassenaam, melding), als lijst.
4
De oorspronkelijke fout doorgeven
Maak async strict_values(jobs) met het normale gather-foutbeleid. Verzamel de bronnen samen; bij een gewone fout moet precies het oorspronkelijke exceptionobject doorgaan. Annuleer de andere bron hierbij niet zelf. De oefenomgeving handelt haar verdere levensduur af. Bij succes geef je de lijst echte resultaten in invoervolgorde terug; een lege bronnenlijst geeft [].
Samenvatting
Gather verzamelt succesvolle resultaten in argumentvolgorde, onafhankelijk van de eindvolgorde.
Met * pak je een lijst awaitables uit; voer iedere bron eenmaal uit.
Kies bewust tussen een fout laten doorgaan en foutobjecten als deelresultaten behandelen.
Hierna onderzoek je hoe TaskGroup verwante taken bij een fout gezamenlijk afrondt.