Beim Programmieren in Python — und besonders in Data-Science-Projekten — laufen wir früher oder später auf Fehler.
Zum Beispiel:
- Eine Datei ist nicht vorhanden.
- Ein Wert ist vom falschen Typ (z. B. ein String statt einer Zahl).
- Ein Modell-Training bricht ab, weil Speicher fehlt.
Damit der Code nicht sofort abstürzt und man versteht, warum etwas schiefgeht, gibt es in Python Fehlerbehandlung und Logging.
Beides sind zentrale Werkzeuge, um stabile und nachvollziehbare Programme zu schreiben.
Fehler (Exceptions) in Python
In Python nennt man Fehler Exceptions (engl. für „Ausnahmen“).
Eine Exception bedeutet: „Etwas Unvorhergesehenes ist passiert, und der normale Ablauf kann nicht fortgesetzt werden.“
Beispiele für eingebaute Exceptions:
ValueError→ wenn ein Wert nicht passt (z. B.int("abc"))TypeError→ wenn der Datentyp nicht stimmt (z. B.len(5))FileNotFoundError→ wenn eine Datei nicht existiertZeroDivisionError→ bei Division durch null
Fehler abfangen mit try und except
Man kann Fehler gezielt abfangen, um kontrolliert zu reagieren.
try:
zahl = int("abc") # das löst einen ValueError aus
except ValueError as e:
print("Konvertierung fehlgeschlagen:", e)
Erklärung:
try: Python versucht, den Code darin auszuführen.except: Falls ein bestimmter Fehler auftritt, wird dieser Teil ausgeführt.as e: Speichert die Fehlermeldung in einer Variablen, sodass man sie weiterverwenden kann.
So bleibt das Programm lauffähig, auch wenn ein Teil fehlschlägt.
Mehrere Fehler abfangen
Man kann verschiedene Fehlerarten unterschiedlich behandeln:
try:
with open("daten.csv") as f:
inhalt = f.read()
except FileNotFoundError:
print("Datei nicht gefunden – bitte Pfad prüfen.")
except PermissionError:
print("Keine Berechtigung zum Lesen der Datei.")
Fehler weitergeben (raise)
Manchmal möchte man Fehler bewusst weiterwerfen, zum Beispiel in einer Funktion:
def teile(a, b):
if b == 0:
raise ValueError("Division durch 0 nicht erlaubt")
return a / b
Hier verhindert man, dass ein ungültiger Wert einfach stillschweigend verarbeitet wird.
Aufräumen mit finally
Wenn man z. B. Dateien oder Datenbankverbindungen nutzt, muss man sicherstellen, dass Ressourcen wieder freigegeben werden.
Dafür gibt es den Block finally:
try:
f = open("daten.csv")
# ... etwas mit der Datei tun ...
finally:
f.close() # wird garantiert ausgeführt
finally läuft immer, egal ob ein Fehler aufgetreten ist oder nicht.
Logging – Was ist das?
Logging bedeutet: Informationen über den Programmablauf (und auch Fehler) systematisch protokollieren.
Das ist viel besser als print(), weil:
- Logs haben Level (z. B. INFO, WARNING, ERROR).
- Logs können in Dateien geschrieben werden.
- Man kann später nachverfolgen, wann und wo etwas passiert ist.
Das logging-Modul
Python hat ein eingebautes Modul namens logging.
Ein einfaches Beispiel:
import logging
logging.basicConfig(level=logging.INFO)
logging.info("Starte das Programm")
logging.warning("Dies ist eine Warnung")
logging.error("Ein Fehler ist aufgetreten")
Erklärung:
basicConfig(level=...)legt die minimale Wichtigkeit fest, ab der Logs angezeigt werden.info,warning,errorsind Methoden mit verschiedenen Log-Leveln.
Wichtige Log-Level
- DEBUG: sehr detaillierte Infos (z. B. Zwischenergebnisse, nur für Entwickler:innen nützlich)
- INFO: normale Statusmeldungen (z. B. „Training gestartet“)
- WARNING: Hinweis, dass etwas unerwartet ist, aber nicht kritisch
- ERROR: ein Fehler ist passiert, der Code kann evtl. nicht weiterlaufen
- CRITICAL: sehr schwerer Fehler, Programm muss beendet werden
Logs in eine Datei schreiben
Sehr praktisch in Data-Science-Projekten, wenn man lange Pipelines oder Trainings laufen lässt:
import logging
logging.basicConfig(
filename="pipeline.log",
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
logging.info("Pipeline gestartet")
logging.error("Ein Fehler in Schritt 3")
Hier wird alles in die Datei pipeline.log geschrieben, mit Zeitstempel, Log-Level und Nachricht.
Kombination Fehlerbehandlung + Logging
Häufig nutzt man beides zusammen:
import logging
logging.basicConfig(level=logging.INFO)
try:
daten = [1, 2, 3]
wert = daten[5] # IndexError
except IndexError as e:
logging.error("Fehler beim Zugriff auf Liste: %s", e)
So wird der Fehler nicht nur abgefangen, sondern auch protokolliert.
Best Practices
- Nicht alles abfangen: Nur Fehler behandeln, die man sinnvoll verarbeiten kann.
- Logs statt Prints: Logs sind strukturierter und langfristig nützlicher.
- Kombinieren: Fehler abfangen, sinnvolle Fehlermeldung loggen, Programm stabil halten.
- Im Data-Science-Kontext:
- Logs für Datenqualität (z. B. „10% Missing Values gefunden“)
- Fehlerbehandlung für Inputdaten (z. B. falsches Dateiformat)