Ga naar hoofdinhoud

15f Zelf een fout opwerpen

Tot nu toe kwamen de fouten van Python zelf. Je kunt er ook zelf een opwerpen, met raise. Dat doe je als je functie iets krijgt waar hij niets mee kan:

def zet_leeftijd(leeftijd):
if leeftijd < 0:
raise ValueError("Een leeftijd kan niet negatief zijn.")
return leeftijd


print(zet_leeftijd(15))
print(zet_leeftijd(-3))

Uitvoer:

15
ValueError: Een leeftijd kan niet negatief zijn.

raise stopt de functie meteen, net als een fout van Python zelf. De tekst tussen de haakjes is de melding die wie de functie gebruikt, te zien krijgt. ValueError past hier: de waarde klopt niet.

Afvangen wat je zelf opwerpt​

Wie de functie aanroept, vangt jouw fout af zoals elke andere:

def zet_leeftijd(leeftijd):
if leeftijd < 0:
raise ValueError("Een leeftijd kan niet negatief zijn.")
return leeftijd


try:
zet_leeftijd(-3)
except ValueError as fout:
print(f"Niet gelukt: {fout}")

Uitvoer:

Niet gelukt: Een leeftijd kan niet negatief zijn.

Zo kiest de functie wát er mis is, en kiest wie hem aanroept wat er dan gebeurt.

In een klasse​

In les 14f gaf neem_op van de rekening False terug als het saldo te laag was. Wie dat vergat te controleren, merkte niets. Met raise kan dat niet ongemerkt:

class Rekening:
def __init__(self, eigenaar):
self.eigenaar = eigenaar
self.saldo = 0

def neem_op(self, bedrag):
if bedrag > self.saldo:
raise ValueError(f"Te weinig saldo: {self.saldo} euro")
self.saldo -= bedrag


rekening = Rekening("Sara")
try:
rekening.neem_op(50)
except ValueError as fout:
print(fout)

Uitvoer:

Te weinig saldo: 0 euro

Opdracht 15f.1: Een geldige maand​

Laat maandnaam een ValueError opwerpen als het nummer niet tussen 1 en 12 ligt, met de melding Een maand gaat van 1 tot en met 12. Vang de fout af bij de aanroep.

Verwachte uitvoer:

maart
Een maand gaat van 1 tot en met 12.
namen = [
    "januari", "februari", "maart", "april", "mei", "juni",
    "juli", "augustus", "september", "oktober", "november", "december",
]


def maandnaam(nummer):
    return namen[nummer - 1]


print(maandnaam(3))
print(maandnaam(13))
Klik hier voor een tip.

Controleer in de functie met if nummer < 1 or nummer > 12: en werp dan de fout op. Zet de tweede print in een try met except ValueError as fout:.

Klik hier voor de oplossing.
namen = [
"januari", "februari", "maart", "april", "mei", "juni",
"juli", "augustus", "september", "oktober", "november", "december",
]


def maandnaam(nummer):
if nummer < 1 or nummer > 12:
raise ValueError("Een maand gaat van 1 tot en met 12.")
return namen[nummer - 1]


print(maandnaam(3))
try:
print(maandnaam(13))
except ValueError as fout:
print(fout)

Uitvoer:

maart
Een maand gaat van 1 tot en met 12.

Opdracht 15f.2: Niet storten wat negatief is​

Geef Rekening een methode stort(bedrag) die een ValueError opwerpt als het bedrag 0 of kleiner is, met de melding Storten kan alleen met een positief bedrag.

Verwachte uitvoer:

Saldo: 20 euro
Storten kan alleen met een positief bedrag.
Saldo: 20 euro
class Rekening:
    def __init__(self, eigenaar):
        self.eigenaar = eigenaar
        self.saldo = 0

    def stort(self, bedrag):
        self.saldo += bedrag


rekening = Rekening("Sara")
rekening.stort(20)
print(f"Saldo: {rekening.saldo} euro")
try:
    rekening.stort(-5)
except ValueError as fout:
    print(fout)
print(f"Saldo: {rekening.saldo} euro")
Klik hier voor een tip.

Zet de if met raise bovenaan de methode, vóór self.saldo += bedrag. Zo verandert het saldo niet als het bedrag niet klopt.

Klik hier voor de oplossing.
class Rekening:
def __init__(self, eigenaar):
self.eigenaar = eigenaar
self.saldo = 0

def stort(self, bedrag):
if bedrag <= 0:
raise ValueError("Storten kan alleen met een positief bedrag.")
self.saldo += bedrag


rekening = Rekening("Sara")
rekening.stort(20)
print(f"Saldo: {rekening.saldo} euro")
try:
rekening.stort(-5)
except ValueError as fout:
print(fout)
print(f"Saldo: {rekening.saldo} euro")

Uitvoer:

Saldo: 20 euro
Storten kan alleen met een positief bedrag.
Saldo: 20 euro

Zonder de controle had de startcode het saldo stil op 15 gezet.