Python uitzonderingsafhandeling meesteren: Een uitgebreide gids
Python biedt twee zeer belangrijke functies om onverwachte fouten in je Python-programma's af te handelen en debug-mogelijkheden toe te voegen:
Uitzonderingsafhandeling − Dit wordt in deze tutorial behandeld. Hier is een lijst standaard uitzonderingen beschikbaar in Python: Standaard uitzonderingen.
Asserties − Dit wordt behandeld in de Asserties in Python tutorial.
Lijst van standaard uitzonderingen:
| Nr. | Uitzonderingsnaam & Beschrijving |
|---|---|
| 1 | Exception Basisklasse voor alle uitzonderingen |
| 2 | StopIteration Opgegooid wanneer de next()-methode van een iterator niet naar een object wijst. |
| 3 | SystemExit Opgegooid door de sys.exit()-functie. |
| 4 | StandardError Basisklasse voor alle ingebouwde uitzonderingen behalve StopIteration en SystemExit. |
| 5 | ArithmeticError Basisklasse voor alle fouten die optreden bij numerieke berekeningen. |
| 6 | OverflowError Opgegooid wanneer een berekening de maximumlimiet voor een numeriek type overschrijdt. |
| 7 | FloatingPointError Opgegooid wanneer een drijvendekomma-berekening mislukt. |
| 8 | ZeroDivisionError Opgegooid wanneer deling of modulo door nul plaatsvindt voor alle numerieke typen. |
| 9 | AssertionError Opgegooid in geval van mislukking van de Assert-instructie. |
| 10 | AttributeError Opgegooid in geval van mislukking van attribuutreferentie of toewijzing. |
| 11 | EOFError Opgegooid wanneer er geen invoer is van zowel de raw_input() als input()-functie en het einde van het bestand bereikt is. |
| 12 | ImportError Opgegooid wanneer een import-instructie mislukt. |
| 13 | KeyboardInterrupt Opgegooid wanneer de gebruiker de programma-uitvoering onderbreekt, meestal door Ctrl+c in te drukken. |
| 14 | LookupError Basisklasse voor alle opzoekingfouten. |
| 15 | IndexError Opgegooid wanneer een index niet in een reeks gevonden wordt. |
| 16 | KeyError Opgegooid wanneer de opgegeven sleutel niet in het woordenboek gevonden wordt. |
| 17 | NameError Opgegooid wanneer een identificator niet in de lokale of globale naamruimte gevonden wordt. |
| 18 | UnboundLocalError Opgegooid wanneer geprobeerd wordt een lokale variabele in een functie of methode te benaderen maar geen waarde is toegewezen. |
| 19 | EnvironmentError Basisklasse voor alle uitzonderingen die buiten de Python-omgeving optreden. |
| 20 | IOError Opgegooid wanneer een invoer/uitvoer-bewerking mislukt, zoals de print-instructie of de open()-functie bij het proberen een niet-bestaand bestand te openen. |
| 21 | IOError Opgegooid voor besturingssysteemgerelateerde fouten. |
| 22 | SyntaxError Opgegooid wanneer er een fout in Python-syntaxis is. |
| 23 | IndentationError Opgegooid wanneer inspringing niet correct gespecificeerd is. |
| 24 | SystemError Opgegooid wanneer de interpreter een intern probleem vindt, maar de Python-interpreter niet afsluit bij deze fout. |
| 25 | SystemExit Opgegooid wanneer Python-interpreter wordt beëindigd met sys.exit(). Als niet afgehandeld in de code, zorgt dit ervoor dat de interpreter afsluit. |
| 26 | TypeError Opgegooid wanneer een operatie of functie geprobeerd wordt die ongeldig is voor het gespecificeerde datatype. |
| 27 | ValueError Opgegooid wanneer de ingebouwde functie voor een datatype het geldige type argumenten heeft, maar de argumenten ongeldige waarden hebben. |
| 28 | RuntimeError Opgegooid gegenereerde fout niet in een categorie valt. |
| 29 | NotImplementedError Opgegooid wanneer een abstracte methode die geïmplementeerd moet worden in een afgeleide klasse niet daadwerkelijk geïmplementeerd is. |
Asserties in Python
Een assertie is een sanity-check die je kunt in- of uitschakelen wanneer je klaar bent met testen van het programma.
De eenvoudigste manier om een assertie te begrijpen is om het te vergelijken met een raise-if-instructie (of nauwkeuriger, een raise-if-not-instructie). Een expressie wordt getest, en als het resultaat false is, wordt een uitzondering opgegooid.
Asserties worden uitgevoerd door de assert-instructie, het nieuwste sleutelwoord in Python, geïntroduceerd in versie 1.5.
Programmeurs plaatsen vaak asserties aan het begin van een functie om geldige invoer te controleren, en na een functie-aanroep om geldige uitvoer te controleren.
De assert-instructie
Wanneer het een assert-instructie tegenkomt, evalueert Python de bijbehorende expressie, die hopelijk true is. Als de expressie false is, gooit Python een AssertionError-uitzondering op.
De syntaxis voor assert is:
assert Expressie[, Argumenten]
Als de assertie mislukt, gebruikt Python ArgumentExpressie als argument voor de AssertionError. AssertionError-uitzonderingen kunnen worden gevangen en afgehandeld zoals elke andere uitzondering met de try-except-instructie, maar als ze niet afgehandeld worden, beëindigen ze het programma en produceren ze een traceback.
Voorbeeld
Hier is een functie die een temperatuur van graden Kelvin omzet naar graden Fahrenheit. Aangezien nul graden Kelvin zo koud als het kan worden is, stopt de functie als het een negatieve temperatuur ziet:
#!/usr/bin/python
def KelvinNaarFahrenheit(Temperatuur):
assert (Temperatuur >= 0), "Kouder dan absoluut nul!"
return ((Temperatuur-273)*1.8)+32
print(KelvinNaarFahrenheit(273))
print(int(KelvinNaarFahrenheit(505.78)))
print(KelvinNaarFahrenheit(-5))
Wanneer de bovenstaande code wordt uitgevoerd, produceert dit het volgende resultaat:
32.0 451 Traceback (most recent call last): File "test.py", line 9, inprint(KelvinNaarFahrenheit(-5)) File "test.py", line 4, in KelvinNaarFahrenheit assert (Temperatuur >= 0),"Kouder dan absoluut nul!" AssertionError: Kouder dan absoluut nul!
Wat is een uitzondering?
Een uitzondering is een gebeurtenis die optreedt tijdens de uitvoering van een programma die de normale stroom van de programma-instructies verstoort. In het algemeen, wanneer een Python-script een situatie tegenkomt waar het niet mee overweg kan, gooit het een uitzondering op. Een uitzondering is een Python-object dat een fout vertegenwoordigt.
Wanneer een Python-script een uitzondering opgooit, moet het deze onmiddellijk afhandelen, anders beëindigt het en stopt het.
Een uitzondering afhandelen
Als je wat verdachte code hebt die een uitzondering kan opgooien, kun je je programma beschermen door de verdachte code in een try:-blok te plaatsen. Na het try:-blok, voeg een except:-instructie toe, gevolgd door een blok code dat het probleem zo elegant mogelijk afhandelt.
Syntaxis
Hier is een eenvoudige syntaxis van try....except...else-blokken:
try:
Je doet je operaties hier;
......................
except UitzonderingI:
Als er UitzonderingI is, voer dan dit blok uit.
except UitzonderingII:
Als er UitzonderingII is, voer dan dit blok uit.
......................
else:
Als er geen uitzondering is, voer dan dit blok uit.
Hier zijn een paar belangrijke punten over de bovenstaande syntaxis:
Een enkele try-instructie kan meerdere except-instructies hebben. Dit is nuttig wanneer het try-blok instructies bevat die verschillende typen uitzonderingen kunnen opgooien.
Je kunt ook een generieke except-clausule opgeven, die elke uitzondering afhandelt.
Na de except-clausule(s) kun je een else-clausule opnemen. De code in het else-blok wordt uitgevoerd als de code in het try:-blok geen uitzondering opgooit.
Het else-blok is een goede plek voor code die geen bescherming van het try:-blok nodig heeft.
Voorbeeld
Dit voorbeeld opent een bestand, schrijft inhoud in het bestand en komt netjes uit omdat er geen probleem is:
#!/usr/bin/python
try:
fh = open("testfile", "w")
fh.write("Dit is mijn testbestand voor uitzonderingsafhandeling!!")
except IOError:
print("Fout: kan bestand niet vinden of gegevens lezen")
else:
print("Inhoud succesvol in het bestand geschreven")
fh.close()
Dit produceert het volgende resultaat:
Inhoud succesvol in het bestand geschreven
Voorbeeld
Dit voorbeeld probeert een bestand te openen waar je geen schrijfrechten hebt, dus het gooit een uitzondering op:
#!/usr/bin/python
try:
fh = open("testfile", "r")
fh.write("Dit is mijn testbestand voor uitzonderingsafhandeling!!")
except IOError:
print("Fout: kan bestand niet vinden of gegevens lezen")
else:
print("Inhoud succesvol in het bestand geschreven")
Dit produceert het volgende resultaat:
Fout: kan bestand niet vinden of gegevens lezen
De except-clausule zonder uitzonderingen
Je kunt de except-instructie ook zonder gedefinieerde uitzonderingen gebruiken als volgt:
try:
Je doet je operaties hier;
......................
except:
Als er een uitzondering is, voer dan dit blok uit.
......................
else:
Als er geen uitzondering is, voer dan dit blok uit.
Dit soort try-except-instructie vangt alle uitzonderingen die optreden. Het gebruik van dit soort try-except-instructie wordt niet als een goede programmeerpraktijk beschouwd, omdat het alle uitzonderingen vangt maar de programmeur niet de hoofdzaak van het probleem laat identificeren dat kan optreden.
De except-clausule met meerdere uitzonderingen
Je kunt ook dezelfde except-instructie gebruiken om meerdere uitzonderingen af te handelen als volgt:
try:
Je doet je operaties hier;
......................
except(Uitzondering1[, Uitzondering2[,...UitzonderingN]]]):
Als er een uitzondering uit de gegeven uitzonderingslijst is, voer dan dit blok uit.
......................
else:
Als er geen uitzondering is, voer dan dit blok uit.
De try-finally clausule
Je kunt een finally:-blok samen met een try:-blok gebruiken. Het finally-blok is een plek om code te zetten die moet worden uitgevoerd, of het try-blok nu een uitzondering opgooit of niet. De syntaxis van de try-finally-instructie is:
try:
Je doet je operaties hier;
......................
Vanwege een uitzondering, kan dit overgeslagen worden.
finally:
Dit zou altijd uitgevoerd worden.
......................
Je kunt geen else-clausule gebruiken samen met een finally-clausule.
Voorbeeld
#!/usr/bin/python
try:
fh = open("testfile", "w")
fh.write("Dit is mijn testbestand voor uitzonderingsafhandeling!!")
finally:
print("Fout: kan bestand niet vinden of gegevens lezen")
Als je geen toestemming hebt om het bestand in schrijfmodus te openen, dan produceert dit het volgende resultaat:
Fout: kan bestand niet vinden of gegevens lezen
Hetzelfde voorbeeld kan netter geschreven worden als volgt:
#!/usr/bin/python
try:
fh = open("testfile", "w")
try:
fh.write("Dit is mijn testbestand voor uitzonderingsafhandeling!!")
finally:
print("Ga het bestand sluiten")
fh.close()
except IOError:
print("Fout: kan bestand niet vinden of gegevens lezen")
Wanneer een uitzondering in het try-blok wordt opgegooid, gaat de uitvoering onmiddellijk naar het finally-blok. Na uitvoering van alle instructies in het finally-blok, wordt de uitzondering opnieuw opgegooid en in de except-instructies afgehandeld als deze aanwezig zijn in de volgende hogere laag van de try-except-instructie.
Argument van een uitzondering
Een uitzondering kan een argument hebben, wat een waarde is die aanvullende informatie over het probleem geeft. De inhoud van het argument varieert per uitzondering. Je vangt een uitzonderingsargument op door een variabele in de except-clausule op te geven als volgt:
try:
Je doet je operaties hier;
......................
except Uitzonderingstype, Argument:
Je kunt de waarde van Argument hier printen...
Als je de code schrijft om een enkele uitzondering af te handelen, kun je een variabele laten volgen op de naam van de uitzondering in de except-instructie. Als je meerdere uitzonderingen vangt, kun je een variabele laten volgen op de tuple van de uitzondering.
Deze variabele ontvangt de waarde van de uitzondering, meestal de oorzaak van de uitzondering. De variabele kan een enkele waarde of meerdere waarden in de vorm van een tuple ontvangen. Deze tuple bevat meestal de foutstring, het foutnummer en een foutlocatie.
Voorbeeld
Hieronder volgt een voorbeeld voor een enkele uitzondering:
#!/usr/bin/python
# Definieer een functie hier.
def temp_convert(var):
try:
return int(var)
except ValueError, Argument:
print("Het argument bevat geen nummers\n", Argument)
# Roep bovenstaande functie hier aan.
temp_convert("xyz");
Dit produceert het volgende resultaat:
Het argument bevat geen nummers invalid literal for int() with base 10: 'xyz'
Een uitzondering opgooien
Je kunt uitzonderingen op verschillende manieren opgooien door de raise-instructie te gebruiken. De algemene syntaxis voor de raise-instructie is als volgt.
Syntaxis
raise [Uitzondering [, args [, traceback]]]
Hier is Uitzondering het type uitzondering (bijvoorbeeld, NameError) en argument is een waarde voor het uitzonderingsargument. Het argument is optioneel; als niet opgegeven, is het uitzonderingsargument None.
Het laatste argument, traceback, is ook optioneel (en zelden in de praktijk gebruikt), en als aanwezig, is het het traceback-object dat voor de uitzondering gebruikt wordt.
Voorbeeld
Een uitzondering kan een string, een klasse of een object zijn. De meeste uitzonderingen die de Python-kern opgooit, zijn klassen, met een argument dat een instantie van de klasse is. Nieuwe uitzonderingen definiëren is vrij eenvoudig en kan als volgt gedaan worden:
def functieNaam( level ):
if level < 1:
raise "Ongeldig niveau!", level
# De code hieronder zou niet uitgevoerd worden
# als we de uitzondering opgooien
Let op: Om een uitzondering te vangen, moet een "except"-clausule verwijzen naar dezelfde uitzondering die opgegooid wordt, ofwel klasse-object of simpele string. Bijvoorbeeld, om bovenstaande uitzondering te vangen, moeten we de except-clausule als volgt schrijven:
try:
Business Logic hier...
except "Ongeldig niveau!":
Uitzonderingsafhandeling hier...
else:
Rest van de code hier...
Gebruiker-gedefinieerde uitzonderingen
Python stelt je ook in staat om je eigen uitzonderingen te maken door klassen af te leiden van de standaard ingebouwde uitzonderingen.
Hier is een voorbeeld gerelateerd aan RuntimeError. Hier wordt een klasse aangemaakt die een subklasse is van RuntimeError. Dit is nuttig wanneer je meer specifieke informatie wilt tonen wanneer een uitzondering gevangen wordt.
In het try-blok wordt de gebruiker-gedefinieerde uitzondering opgegooid en in het except-blok gevangen. De variabele e wordt gebruikt om een instantie van de klasse Networkerror aan te maken.
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
Zodra je bovenstaande klasse gedefinieerd hebt, kun je de uitzondering als volgt opgooien:
try:
raise Networkerror("Slechte hostname")
except Networkerror, e:
print(e.args)
Python
- Python Datatypes onder de knie krijgen: Een praktische gids
- Python Operators onder de knie krijgen: Een uitgebreide gids
- Python Pass Statement onder de knie krijgen: Een praktische gids
- Python Functie-argumenten onder de knie krijgen: Positionele, Keyword en Default Parameters
- Python-dictionaries beheersen: aanmaken, manipuleren en geavanceerde technieken
- Python-fouten & ingebouwde exceptions beheersen
- Python-exception handling: try, except, else en finally uitgelegd
- Python-custom exceptions: een praktische gids
- Python-iterators: hoe ze werken en hoe je je eigen maakt
- Python-closures uitgelegd: hoe geneste functies variabelen vangen
- Python datetime beheersen: praktische gids voor datums, tijden en tijdzones