Een aparte succesroute
Maak classify(text, audit): zet text om met int. Voeg bij succes valid toe aan audit en geef het getal terug; voeg bij ValueError invalid toe en geef None terug. Voeg in deze functie geen closed toe.
Een invoer is gecontroleerd en mag nu verder worden verwerkt. Maar een tijdelijke werkstap moet ook worden afgesloten als de invoer onbruikbaar blijkt. Succes verwerken en opruimen zijn twee verschillende verantwoordelijkheden; Python geeft ze elk een eigen plaats.
Een else-blok achter try en except wordt uitgevoerd wanneer het try normaal tot zijn einde komt. Een afgehandelde fout neemt deze route niet. Een vroegtijdige return vanuit try komt evenmin bij dit else terecht.
Dat is nuttig wanneer de handler uitsluitend bij één kwetsbare bewerking hoort. Je kunt de conversie in try houden en de vervolgbewerking in else plaatsen. Een fout uit die vervolgbewerking valt dan buiten de handlers van hetzelfde try.
Je kent die grens al uit de vorige les, waar de vervolgbewerking na het hele try/except stond. else drukt hier dezelfde bedoeling zichtbaar uit: dit deel hoort bij een geslaagde poging. Het is geen algemene route voor alles wat na een fout nog moet gebeuren.
Een finally-blok is bedoeld voor afsluitende handelingen wanneer Python de constructie verlaat. Dat gebeurt bij succes, na een afgehandelde fout en bij het doorgeven van een fout. Ook een return uit een eerder blok laat eerst de finally uitvoeren.
In het voorbeeld gebruiken we een lijst als eenvoudig logboek. De woorden tonen de volgorde van de handelingen; er wordt nog geen bestand geopend. Voorspel de lijst voordat je de code uitvoert.
audit = []
try:
number = int("6")
except ValueError:
audit.append("invalid")
else:
audit.append("valid")
finally:
audit.append("closed")
print(audit)['valid', 'closed']
De conversie slaagt, dus else voegt valid toe. Daarna voegt finally closed toe. Bij ongeldige invoer zou in dit voorbeeld de handler invalid toevoegen, gevolgd door dezelfde afsluiting.
| Route uit het try-blok | else | finally |
|---|---|---|
| Normaal einde zonder fout | Ja | Ja |
| Afgehandelde fout | Nee | Ja |
| Doorgegeven fout | Nee | Ja |
| Vroegtijdige return | Nee | Ja |
Het volgende voorbeeld heeft bewust geen handler voor de conversiefout. Toch verschijnt eerst de afsluitende melding. De fout blijft daarna bestaan en wordt zichtbaar in de traceback.
try:
number = int("mis")
finally:
print("gesloten")gesloten ValueError: invalid literal for int() with base 10: 'mis'
finally maakt de invoer dus niet geldig en verandert een exception niet vanzelf in een normale retourwaarde. Het voegt alleen zijn afsluitende handelingen toe. Een proces dat abrupt wordt beëindigd, kan uiteraard geen verdere Python-code meer uitvoeren.
Een return in finally kan een eerder gekozen resultaat vervangen en zelfs een nog door te geven fout onderdrukken. De aanroeper ziet dan een keurige waarde terwijl de eigenlijke bewerking mislukte. Zet een gewone succes- of terugvalwaarde daarom in de bijbehorende route, en gebruik finally hier uitsluitend voor het logboek.
Let ook op de plaats van het logboek. Alleen na int(text) een woord toevoegen mist precies het foutpad: die volgende regel wordt bij een mislukte conversie nooit bereikt. De echte afsluiting hoort bij het verlaten van de constructie, niet alleen bij een geslaagde berekening.
De functies krijgen een bestaande lijst audit mee waar dat bij de opdracht staat. Voeg gebeurtenissen aan diezelfde lijst toe en behoud eerdere inhoud. De controles bekijken die lijst ook wanneer de functie een echte fout doorgeeft; een zelf teruggegeven lijst met succeswoorden is daarvoor geen vervanging.
classify toont eerst alleen de keuze tussen succes en een afgehandelde fout. finish_count bewaakt de grens rond een vervolgbewerking. Daarna voeg je met close_count en process_count de afsluiting en de juiste volgorde toe.
Maak classify(text, audit): zet text om met int. Voeg bij succes valid toe aan audit en geef het getal terug; voeg bij ValueError invalid toe en geef None terug. Voeg in deze functie geen closed toe.
Maak finish_count(text, finish): geef bij een conversie-ValueError None; roep bij succes finish(number) aan en geef dat resultaat terug. Een fout uit finish moet worden doorgegeven.
Maak close_count(text, audit): geef int(text) terug en voeg bij zowel succes als een doorgegeven fout precies eenmaal closed aan dezelfde audit-lijst toe. Bewaar eerdere inhoud.
Maak process_count(text, audit): geef bij succes het getal terug en voeg valid toe; geef bij ValueError None en voeg invalid toe. Voeg in beide routes daarna precies eenmaal closed toe. Bewaar eerdere audit-inhoud.
else hoort bij een try-blok dat normaal tot zijn einde komt.finally voert afsluiting uit vóór een return of een doorgegeven fout.finally en laat de oorspronkelijke uitkomst intact.Hierna werp je zelf fouten en bewaar je de oorzaak bij een vertaling.
Voer je code uit en ontdek
wat je hebt gemaakt.
Je hoeft het niet in één keer goed te doen. Na het uitvoeren zie je hier welke stappen al kloppen.