Abschnitt 9 · Lektion 2
try und except
In einer Liste mit Preisen steht ein einziger als Wort da, zwei Euro statt 2.00, und das ganze
Programm ist vorbei. Solange der Fehler im Code steckt, ist das richtig. Dann soll er laut sein.
Anders ist es bei Fehlern, die von draußen kommen. Eine Datei, die jemand von Hand gefüllt hat, oder eine Antwort, die jemand eingetippt hat, enthält irgendwann ein Wort statt einer Zahl. Das passiert nicht aus Versehen. Es ist der Normalfall, und man muss damit rechnen.
preise = ["2.49", "1.19", "zwei Euro", "3.29"]
summe = 0
for preis in preise:
summe = summe + float(preis)
print(f"Zusammen: {summe:.2f} Euro") Vom ganzen Programm bleibt nur ValueError: could not convert string to float: 'zwei Euro'. Die
zwei Preise davor waren schon zusammengezählt, der danach wäre es auch gewesen. Ausgegeben wird
nichts davon. Ein einziger Eintrag, und die ganze Rechnung ist weg.
try und except
preise = ["2.49", "1.19", "zwei Euro", "3.29"]
summe = 0
for preis in preise:
try:
summe = summe + float(preis)
except ValueError:
print("Übersprungen:", preis)
print(f"Zusammen: {summe:.2f} Euro") Unter try (versuchen) steht ein Block, von dem du weißt, dass er schiefgehen kann. Darunter folgt
except mit der Fehlerart, die du erwartest, hier ValueError. Wenn dieser Fehler im try-Block
auftritt, bricht Python nicht ab, sondern springt in den except-Block, führt ihn aus und macht
danach hinter dem Ganzen weiter. Geht alles gut, wird der except-Block übersprungen. Eingerückt
sind beide Blöcke wie bei if und else.
Bei zwei Euro steht im Beispiel deshalb die Zeile Übersprungen: zwei Euro. Die Schleife läuft
weiter, und am Ende kommt Zusammen: 6.97 Euro heraus, die Summe der drei Preise, die sich lesen
ließen.
Ein Fehler, der erst beim Laufen entsteht, heißt bei Python übrigens Ausnahme (exception). Daher
hat except seinen Namen.
Wichtig ist, wo das try steht. Davon hängt ab, was nach dem Fehler noch passiert. Hier steht es in
der Schleife, nur um die eine Zeile, die scheitern kann, und deshalb geht es mit dem nächsten Preis
weiter. Stünde es um die ganze Schleife, wäre nach dem ersten Fehler auch die Schleife vorbei. Nur
eben ohne Traceback. Je kleiner der try-Block, desto genauer ist klar, womit man gerechnet hat.
Was genau schiefging
preise = ["2.49", "1,19", "", "3.29"]
summe = 0
for preis in preise:
try:
summe = summe + float(preis)
except ValueError as fehler:
print("Übersprungen:", fehler)
print(f"Zusammen: {summe:.2f} Euro") Hinter except ValueError kann as mit einem Namen stehen, hier fehler. Unter diesem Namen hast
du im except-Block den Fehler selbst. print gibt seine Meldung aus, also den Text, der sonst
hinter ValueError: in der letzten Zeile des Tracebacks stünde.
Im Beispiel sind es zwei Meldungen, einmal mit '1,19' und einmal mit ''. Die Anführungszeichen
helfen dabei sehr. Ohne sie stünde beim leeren Text hinter dem Doppelpunkt einfach nichts, und du
wüsstest nicht, ob dort ein Leerzeichen war oder gar nichts.
Zwei Wörter gibt es noch, die man seltener braucht. Ein else: nach dem except läuft nur, wenn im
try kein Fehler auftrat. Ein finally: läuft immer, mit Fehler und ohne. Das ist für
Aufräumarbeiten gedacht, die auf keinen Fall ausfallen dürfen.
Nie einfach alles abfangen
preise = ["2.49", "1.19", "zwei Euro", "3.29"]
summe = 0
for preis in preise:
try:
summe = summe + flaot(preis)
except:
print("Übersprungen:", preis)
print(f"Zusammen: {summe:.2f} Euro") Python erlaubt auch ein except: ganz ohne Fehlerart. Dann wird jeder Fehler abgefangen. Das sieht
praktisch aus und ist der Fehler dieser Lektion.
Im Beispiel steht flaot statt float, ein Tippfehler. Gemeldet wird er nicht. Auch ein
NameError ist ein Fehler, und das except: fängt ihn genauso ab wie die echten Fehler in den
Daten. Jeder Preis wird übersprungen, am Ende stehen 0.00 Euro da, und nirgends steht, warum.
Mit ValueError hinter dem except meldet sich der Tippfehler sofort, als
NameError: name 'flaot' is not defined. Did you mean: 'float'?. Die Fehlerart hinter except ist
das, womit du rechnest. Alles andere ist ein Fehler im Programm und soll laut bleiben. Welche
Fehlerart du brauchst, steht in der letzten Zeile des Tracebacks, den du ohne try bekommen hast.
Im Netz findet man oft except Exception:. Das sieht genauer aus, ist es aber nicht. Exception
ist der Oberbegriff für fast alle Fehlerarten, auch für NameError, und der Tippfehler verschwindet
damit genauso.
Was die Aufgabe will
Für das Sommerfest des Vereins hat jedes Mitglied in eine gemeinsame Liste eingetragen, wie viele Würstchen es essen will. Nicht alle haben eine Zahl geschrieben. Das Programm, das die Liste zusammenzählt, bricht beim ersten Wort ab. Am Ende soll es alle lesbaren Mengen zählen und jede andere melden.
Zum Mitnehmen
Unter try steht, was schiefgehen kann, und unter except, was dann passieren soll. Abgefangen wird immer nur eine bestimmte Fehlerart. Ohne sie verschwinden auch die Fehler, die man unbedingt sehen müsste, zum Beispiel ein Tippfehler im eigenen Code.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.
Was in dieser Lektion steckt
-
Artikel mit 4 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe, dein Code läuft auf einem Server
Öffnet sich mit dem Basis Konto.