Python-custom exceptions: een praktische gids
Python-custom exceptions
In deze tutorial leer je hoe je custom exceptions definieert die op maat zijn voor je behoeften, geïllustreerd met praktische voorbeelden.
Python biedt veel ingebouwde exceptions die fouten signaleren wanneer een programma onverwachte condities tegenkomt. Soms beschrijven de ingebouwde exceptions het probleem niet precies. In die gevallen kun je je eigen custom exception-types aanmaken om je code duidelijker en beter onderhoudbaar te maken.
Custom exceptions aanmaken
Een custom exception definiëren in Python is eenvoudig: maak een nieuwe klasse die erft van de ingebouwde Exception-klasse (of een van zijn subclasses). De meeste standardexceptions erven van Exception, dus je custom klasse integreert naadloos met Python's foutafhandelingssysteem.
> >>> class CustomError(Exception):
... pass
...
> >>> raise CustomError
Traceback (most recent call last):
...
__main__.CustomError
> >>> raise CustomError("Er is een fout opgetreden")
Traceback (most recent call last):
...
__main__.CustomError: Er is een fout opgetreden
Hier is CustomError een user-defined exception die erft van Exception. Het kan gegooid worden met raise en een optioneel bericht. Bij grote projecten is het gebruikelijk om alle custom exceptions in een speciale module te plaatsen (bijv. exceptions.py of errors.py) zodat ze gemakkelijk te vinden en te onderhouden zijn.
Voorbeeld: User-defined exception in Python
Het volgende programma demonstreert hoe custom exceptions gebruikt kunnen worden om gebruikersinput te sturen. Het vraagt herhaaldelijk om een getal tot de gebruiker de opgeslagen waarde raadt. Het programma geeft een hint – of de gok te hoog of te laag is – door een op maat gemaakte exception te gooien.
# Python user-defined exceptions definiëren
class Error(Exception):
"""Basisklasse voor andere exceptions"""
pass
class ValueTooSmallError(Error):
"""Gegooid wanneer invoerwaarde te klein is"""
pass
class ValueTooLargeError(Error):
"""Gegooid wanneer invoerwaarde te groot is"""
pass
# het doelgetal
nummer = 10
# blijven vragen tot de gok correct is
while True:
try:
i_num = int(input("Voer een getal in: "))
if i_num < nummer:
raise ValueTooSmallError
elif i_num > nummer:
raise ValueTooLargeError
break
except ValueTooSmallError:
print("Deze waarde is te klein, probeer opnieuw!")
print()
except ValueTooLargeError:
print("Deze waarde is te groot, probeer opnieuw!")
print()
print("Gefeliciteerd! Je hebt het correct geraden.")
Voorbeeldrun:
Voer een getal in: 12 Deze waarde is te groot, probeer opnieuw! Voer een getal in: 0 Deze waarde is te klein, probeer opnieuw! Voer een getal in: 8 Deze waarde is te klein, probeer opnieuw! Voer een getal in: 10 Gefeliciteerd! Je hebt het correct geraden.
In dit voorbeeld biedt de basisklasse Error een gemeenschappelijke voorouder voor de twee specifieke fouttypen. Deze benadering houdt de exception-hiërarchie helder en stelt je in staat alle gerelateerde fouten met een enkele except Error-clausule te vangen indien gewenst.
Exception-klassen aanpassen
Custom exceptions kunnen ook extra data opslaan of informatiefere berichten presenteren. Dit vereist het overschrijven van __init__ en optioneel __str__. Het volgende illustreert een salaris-validatiescenario.
class SalaryNotInRangeError(Exception):
"""Exception gegooid voor fouten in invoersalaris.
Attributes:
salary -- invoersalaris dat de fout veroorzaakte
message -- uitleg van de fout
"""
def __init__(self, salary, message="Salaris is niet in (5000, 15000) bereik"):
self.salary = salary
self.message = message
super().__init__(self.message)
salaris = int(input("Voer salarisbedrag in: "))
if not 5000 < salaris < 15000:
raise SalaryNotInRangeError(salaris)
Uitvoer
Voer salarisbedrag in: 2000 Traceback (most recent call last): File "<string>", line 17, in <module> raise SalaryNotInRangeError(salaris) __main__.SalaryNotInRangeError: Salaris is niet in (5000, 15000) bereik
Door __init__ te overschrijven, kan de exception de schuldige waarde meedragen. Als je een custom string-representatie wilt, overschrijf __str__ zoals hieronder getoond:
class SalaryNotInRangeError(Exception):
"""Exception gegooid voor fouten in invoersalaris.
Attributes:
salary -- invoersalaris dat de fout veroorzaakte
message -- uitleg van de fout
"""
def __init__(self, salary, message="Salaris is niet in (5000, 15000) bereik"):
self.salary = salary
self.message = message
super().__init__(self.message)
def __str__(self):
return f'{self.salary} → {self.message}'
salaris = int(input("Voer salarisbedrag in: "))
if not 5000 < salaris < 15000:
raise SalaryNotInRangeError(salaris)
Uitvoer
Voer salarisbedrag in: 2000 Traceback (most recent call last): File "/home/user/untitled.py", line 20, in <module> raise SalaryNotInRangeError(salaris) __main__.SalaryNotInRangeError: 2000 → Salaris is niet in (5000, 15000) bereik
Voor een diepere duik in exception-handling patronen, raadpleeg de Python Exception Handling tutorial.
Om meer te leren over het ontwerpen van robuuste applicaties, verken Python Object-Oriented Programming.
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 Object-Oriented Programming beheersen: classes, inheritance, encapsulatie & polymorfisme
- Python-erfelijkheid beheersen: concepten, syntax en praktische voorbeelden
- Python-iterators: hoe ze werken en hoe je je eigen maakt
- type() en isinstance() in Python begrijpen: praktische voorbeelden
- Python uitzonderingsafhandeling meesteren: Een uitgebreide gids