Dateien und Ausnahmen in Python

Lerne, wie Python-Programme mit Dateien arbeiten und auf Fehler reagieren. Lies Textdateien vollständig oder Zeile für Zeile, schreibe Text und hänge ihn mit with-Anweisungen sicher an. Finde Dateien mithilfe relativer und absoluter Pfade und mit pathlib. Lies und schreibe CSV-Daten mit dem Modul csv, auch Zeilen als Wörterbücher. Fange anschließend erwartete Fehler mit try und except ab, verwende else und finally, löse eigene Ausnahmen mit klaren Meldungen aus und erstelle Programme, die fehlende Dateien und fehlerhafte Daten melden, statt abzustürzen.

AnfängerEinheit 8 von 10 in Kurs: Python-Programmierung – Schleifen, Funktionen, Listen und Dateien

Was du lernst

  1. Öffne Textdateien, lies ihren Inhalt passend zur Aufgabe, schreibe und ergänze Text ohne Datenverlust und verarbeite eine Datei Zeile für Zeile, um zu suchen, zu zählen und zu filtern.
    • Eine Textdatei öffnen und ihren Inhalt lesen
      Verbinde ein Programm mit open() mit einer Textdatei, wähle eine passende Lesemethode und wandle den gelesenen Text in nutzbare Daten um.
    • Dateien mit der with-Anweisung automatisch schließen
      Verwende with open(...) as f:, damit Dateien zum richtigen Zeitpunkt geschlossen werden, auch wenn etwas schiefgeht.
    • Text in Dateien schreiben und an Dateien anhängen
      Wähle den richtigen Modus, um eine Datei zu erstellen, zu überschreiben oder zu erweitern, und schreibe Text mit write() und print(), sodass die Zeilen genau wie beabsichtigt entstehen.
    • Zeilen in einer Datei suchen, zählen und filtern
      Verarbeite eine Datei Zeile für Zeile, um die benötigten Zeilen zu finden, sie zu zählen oder ihre Werte zu summieren und die Ergebnisse in eine neue Datei zu schreiben.
  2. Teile Python genau mit, wo sich eine Datei befindet, verstehe, warum ein Programm eine vorhandene Datei manchmal nicht findet, und erstelle Pfade, die unter Windows, macOS und Linux funktionieren.
    • Relative und absolute Pfade richtig verwenden
      Schreibe absolute und relative Pfade, erkenne, von welchem Verzeichnis ein relativer Pfad ausgeht, und vermeide die Fallen umgekehrter Schrägstriche in Windows-Pfaden.
    • Pfade erstellen und Verzeichnisse mit pathlib verwalten
      Verwende Path-Objekte aus dem Modul pathlib, um Pfade zusammenzufügen, zu untersuchen und zu prüfen, Dateien zu finden, Verzeichnisse zu erstellen und kleine Dateien in einem Schritt zu lesen oder zu schreiben.
  3. Verwende das Python-Modul csv, um Tabellendaten aus CSV-Dateien zu lesen, sie in Zahlen umzuwandeln und Ergebnisse als CSV zu schreiben, das Tabellenkalkulationsprogramme öffnen können.
    • CSV-Daten mit csv.reader lesen
      Verstehe, wie eine CSV-Datei eine Tabelle speichert, lies sie mit csv.reader Zeile für Zeile, überspringe die Kopfzeile und wandle die benötigten Werte um.
    • CSV-Dateien mit csv.writer schreiben
      Erstelle CSV-Dateien aus Listen mit csv.writer, sodass Kommas, Anführungszeichen und Zeilenabschlüsse richtig behandelt werden.
    • Mit DictReader und DictWriter über Namen auf Spalten zugreifen
      Lies jede CSV-Zeile als Wörterbuch mit den Einträgen der Kopfzeile als Schlüsseln, filtere und fasse Zeilen anhand von Spaltennamen zusammen und schreibe Wörterbücher zurück in eine CSV-Datei.
  4. Erkenne die Ausnahmen, die Python auslöst, lies einen Traceback, um die Ursache zu finden, fange erwartete Fehler ab und lasse ein Programm weiterlaufen oder beende es mit einer klaren Meldung statt mit einem Absturz.
    • Häufige Ausnahmen erkennen und einen Traceback lesen
      Erkenne, was eine Ausnahme ist, lies einen Traceback von unten nach oben und benenne die häufigen Ausnahmetypen und ihre typischen Ursachen.
    • Ausnahmen mit try und except abfangen
      Schreibe try- und except-Blöcke, die die erwarteten Fehler gezielt abfangen, dem Benutzer eine hilfreiche Meldung geben und unerwartete Fehler weiterhin sichtbar machen.
    • else und finally verwenden und Ausnahmen durch Funktionen verfolgen
      Ergänze eine try-Anweisung um else und finally, sage die Reihenfolge ihrer Blöcke voraus und entscheide, in welcher Funktion eine Ausnahme behandelt werden soll.
    • Datei- und Datenprogramme kontrolliert auf Fehler reagieren lassen
      Verbinde Datei- und Ausnahmebehandlung, sodass fehlende oder gesperrte Dateien und fehlerhafte Daten zu klaren Meldungen, übersprungenen Zeilen oder einem kontrollierten Stopp statt zu einem Absturz führen.
  5. Verwende raise, damit eine Funktion nicht mit fehlerhaften Eingaben weiterarbeitet, wähle passende Ausnahmetypen und Meldungen und gib Fehler weiter oder wandle sie in klarere um.
    • Ausnahmen auslösen, um ungültige Eingaben zurückzuweisen
      Verwende die raise-Anweisung, um zu signalisieren, dass eine Funktion einen Wert erhalten hat, mit dem sie nicht arbeiten kann, und überlasse die Reaktion dem aufrufenden Code.
    • Ausnahmen erneut auslösen, verketten und benutzerdefinierte Ausnahmen definieren
      Gib eine Ausnahme weiter, nachdem du auf sie reagiert hast, wandle einen Fehler auf niedriger Ebene in einen klareren um und erstelle eigene Ausnahmetypen für Probleme, die für dein Programm spezifisch sind.

Dateien und Ausnahmen in Python einfach erklärt

5 Kapitel

1

Textdateien lesen und schreiben

Dateien ermöglichen es einem Programm, Informationen zwischen Durchläufen zu behalten und mit anderswo gesammelten Daten zu arbeiten. Das Lesen bringt Text in den Speicher; das Schreiben speichert Ergebnisse für den nächsten Durchlauf oder eine andere Person. Du wählst eine Lesemethode, steuerst genau, was geschrieben wird, und nutzt Einrückungen, damit Dateien nur so lange geöffnet bleiben, wie sie gebraucht werden. Beispiele zur zeilenweisen Verarbeitung verbinden anschließend Zeichenkettenoperationen, Entscheidungen und Zähler, um aus Rohtext nützliche Ergebnisse zu gewinnen.

1.1 Text in ein Programm lesen

Eine Textdatei bewahrt Informationen auf, nachdem ein Programm beendet wurde. Python verwendet ein Dateiobjekt, das open() zurückgibt, um mit diesen Informationen zu arbeiten. Das Öffnen stellt die Verbindung zur Datei her; ein Lesevorgang ruft ihren Text ab.

Wähle, was du lesen möchtest

Der Standardmodus ist "r" zum Lesen. Ein bloßer Name wird im aktuellen Arbeitsverzeichnis gesucht. Fehlt die Datei dort, löst open() FileNotFoundError aus.

with open("fruit.txt", encoding="utf-8") as f:
    text = f.read()

Angenommen, die Datei hat drei Zeilen, „apple“, „banana“ und „cherry“, alle mit Zeilenabschluss. text ist 'apple\nbanana\ncherry\n'. Die Escape-Sequenz \n steht für ein Zeilenumbruchzeichen. Eine letzte Zeile kann auch ohne Zeilenumbruch enden.

OperationErgebnisNützlich, wenn
f.read()Der gesamte verbleibende Text als eine ZeichenketteDu eine kleine Datei als Ganzes brauchst
f.readline()Die nächste Zeile als ZeichenketteDu jetzt eine Zeile brauchst
f.readlines()Alle verbleibenden Zeilen als ListeDu die Zeilen erneut verwenden möchtest
for line in f:Eine Zeile pro DurchlaufDu Zeilen der Reihe nach verarbeiten kannst

readline() gibt am Dateiende '' zurück. Eine Leerzeile mit Zeilenabschluss ergibt '\n', daher sind eine Leerzeile und das Dateiende verschieden.

Behalte die Dateiposition im Blick

Beim Lesen rückt die Dateiposition vor. Nachdem f.read() die Datei vollständig gelesen hat, gibt ein weiterer Aufruf '' zurück; eine Schleife über dasselbe Objekt hat nichts mehr zu lesen. Öffne die Datei erneut, um von vorn zu beginnen, oder speichere den benötigten Text oder die Zeilen in einer Variablen. read() und readlines() laden den Rest der Datei in den Speicher. Mit einer Schleife direkt über die Datei kannst du eine große Datei Zeile für Zeile verarbeiten.

Zeilen behalten ihre Zeilenumbruchzeichen. print(line) fügt ein eigenes Zeilenumbruchzeichen hinzu, wodurch zusätzliche Leerzeilen auf dem Bildschirm entstehen können. Verwende print(line, end=""), um die ursprünglichen Abstände beizubehalten, oder entferne den Zeilenabschluss vor der Ausgabe. line.rstrip("\n") entfernt Zeilenumbruchzeichen am Ende; line.strip() entfernt zusätzlich Leerzeichen an beiden Enden.

Wandle Text in Zahlen um

Auch Ziffern kommen als Zeichenketten an. Diese Datei enthält die Punktzahlen „72“, „85“ und „90“:

scores = []
with open("scores.txt", encoding="utf-8") as f:
    for line in f:
        scores.append(int(line))
total = sum(scores)
print(total, round(total / len(scores), 2))

Die Liste ist [72, 85, 90], daher gibt das Programm 247 82.33 aus. int() akzeptiert umgebende Leerzeichen und Zeilenumbruchzeichen. Eine leere Zeichenkette oder ein Wort wie "forty" löst ValueError aus.

Lies Zeichen mit der richtigen Zeichenkodierung

Eine Zeichenkodierung ordnet Zeichen gespeicherten Bytes zu. UTF-8 kann Zeichen wie „é“ und Emojis darstellen. Verwende für UTF-8-Dateien ausdrücklich encoding="utf-8". Python 3.15 aktiviert standardmäßig den UTF-8-Modus; ältere Installationen können eine lokale Zeichenkodierung verwenden. Eine falsche Zeichenkodierung kann verstümmelten Text oder UnicodeDecodeError erzeugen. Die ausdrückliche Angabe der Zeichenkodierung wandelt eine anders kodierte Datei nicht in UTF-8 um.

Der with-Block schließt die Datei, wenn er endet. Eine geschlossene Datei kann nicht gelesen werden: Ein weiteres f.read() löst ValueError aus.

Wichtige Erkenntnisse

  • open() gibt ein Dateiobjekt zurück; beim Lesen wird Text ab seiner aktuellen Dateiposition abgerufen.
  • Wähle passend zur Aufgabe eine Zeichenkette, eine Liste von Zeilen oder eine Schleife zur zeilenweisen Verarbeitung.
  • Am Dateiende erhältst du ''; eine Leerzeile kann '\n' ergeben.
  • Wandle Zahlentext vor dem Rechnen mit int() oder float() um.
  • Verwende die zur Datei passende Zeichenkodierung und schließe die Datei, wenn du fertig bist.

1.2 Dateien, die sich am Blockende schließen

Eine offene Datei beansprucht Ressourcen des Betriebssystems. Geschriebener Text kann außerdem in einem Puffer im Speicher warten, bevor er die Datei erreicht. Das Schließen gibt die Ressourcen frei und leert die gepufferte Ausgabe in die Datei. Eine with-Anweisung sorgt an einer klar erkennbaren Stelle im Code für dieses Aufräumen.

Lies innerhalb des Blocks und verwende das Ergebnis danach
with open("notes.txt", encoding="utf-8") as f:
    text = f.read()
print(len(text))

Der Doppelpunkt beginnt den Block. Die eingerückte Zeile wird ausgeführt, während f geöffnet ist. Wenn die Ausführung das nicht eingerückte print() erreicht, ist die Datei geschlossen, aber text bleibt eine gewöhnliche Zeichenkette. Der Name f verweist weiterhin auf das Dateiobjekt; f.closed ist jetzt True.

Dasselbe Muster funktioniert für eine Liste:

with open("fruit.txt", encoding="utf-8") as f:
    lines = f.readlines()
for line in lines:
    print(line.strip().upper())

Die Schleife verwendet bereits in lines eingelesene Daten. Würdest du f.readlines() außerhalb des Blocks platzieren, würde versucht, eine geschlossene Datei zu lesen, und ValueError ausgelöst.

Aufräumen bei verändertem Programmablauf

Betrachte eine Funktion, die die erste Zeile zurückgibt:

def first_line(path):
    with open(path, encoding="utf-8") as f:
        return f.readline().rstrip("\n")

Der Rückgabewert wird innerhalb des Blocks vorbereitet. Python verlässt dann den Block und schließt die Datei, bevor der aufrufende Code den Wert erhält. Die Datei wird auch geschlossen, wenn eine Ausnahme den Block verlässt. Ein manuelles f.close() nach einer fehlschlagenden Anweisung würde nie erreicht.

Dateiobjekte unterstützen dieses Verhalten, weil sie Kontextmanager sind: Objekte, die das Einrichten und Aufräumen rund um einen with-Block organisieren. Du kannst dieses Verhalten nutzen, ohne selbst einen Kontextmanager zu schreiben.

Öffne eine Eingabe- und eine Ausgabedatei zusammen
with open("in.txt", encoding="utf-8") as src, open("out.txt", "w", encoding="utf-8") as dst:
    for line in src:
        dst.write(line.upper())

Jede Eingabezeile wird in Großbuchstaben umgewandelt und in die Ausgabedatei geschrieben. Beide Dateien werden geschlossen, wenn der Block endet. Schlägt das zweite Öffnen fehl, wird die erste, von with bereits geöffnete Datei geschlossen, wenn Python die Anweisung verlässt.

Aufräumen und Fehlerbehandlung haben verschiedene Aufgaben

with fängt Dateifehler nicht ab. Kann open() notes.txt nicht finden, löst es FileNotFoundError aus, bevor der Block ausgeführt wird. Schlägt die Umwandlung einer Zeile mit int() innerhalb des Blocks fehl, wird die Datei geschlossen und die Ausnahme nach außen weitergegeben. Um den Fehler zu behandeln oder eine Meldung anzuzeigen, ist eine passende except-Klausel nötig.

Ein fehlender Doppelpunkt am Ende der with-Zeile verursacht SyntaxError.

Wichtige Erkenntnisse

  • with schließt eine geöffnete Datei beim regulären Verlassen, bei einer Rückgabe und beim Verlassen durch eine Ausnahme.
  • Gespeicherte Zeichenketten und Listen bleiben nach dem Schließen der Datei verwendbar.
  • Die Einrückung markiert den Zeitraum, in dem die Datei geöffnet ist.
  • Das Aufräumen fängt keine Ausnahme ab; zur Fehlerbehandlung brauchst du try und except.

1.3 Text erstellen, ersetzen und anhängen

Das Schreiben beginnt mit einer Entscheidung über vorhandene Daten. Der Modus steuert, ob Python eine Datei liest, ersetzt, erweitert oder erstellt. Triff diese Entscheidung vor dem Aufruf von open(), denn das Ersetzen geschieht sofort.

Wähle den Modus
ModusVorhandene DateiFehlende Datei
"r"Öffnet zum LesenLöst FileNotFoundError aus
"w"Leert und öffnet dann zum SchreibenErstellt sie
"a"Fügt Ausgaben am Ende hinzuErstellt sie
"x"Löst FileExistsError ausErstellt sie

Das Öffnen der einzigen Kopie wichtiger Daten mit "w" zerstört ihren alten Inhalt, selbst wenn kein write() folgt. Verwende beim Erlernen der Datenumwandlung eine separate Ausgabedatei. "x" ist nützlich, wenn das Ersetzen einer vorhandenen Datei verhindert werden muss.

Ein zusätzliches "b", wie in "rb", wählt den Binärmodus für rohe Bytes. Textmodi arbeiten mit Zeichenketten und einer Zeichenkodierung; Binärmodi nehmen kein encoding-Argument entgegen.

Entscheide, wo Zeilen enden
with open("todo.txt", "w", encoding="utf-8") as f:
    f.write("buy milk\n")
    f.write("call Sam\n")

Die Datei enthält die beiden Zeilen „buy milk“ und „call Sam“. write() fügt genau die übergebene Zeichenkette hinzu, ohne automatisches Trennzeichen. Ohne die Zeilenumbruchzeichen würde die Datei "buy milkcall Sam" in einer Zeile enthalten.

write() gibt die Anzahl der geschriebenen Zeichen zurück. Zum Beispiel gibt f.write("Ana,92\n") 7 zurück. Das ist eine Zeichenanzahl und nicht unbedingt die Anzahl der kodierten Bytes auf dem Datenträger. Die Methode nimmt eine Zeichenkette entgegen; f.write(42) löst TypeError aus. Wandle eine Zahl zuerst um, zum Beispiel mit f.write(f"{score}\n").

Vergleiche die Ausgabehilfen

print() kann in eine Datei schreiben:

with open("total.txt", "w", encoding="utf-8") as f:
    print("Total:", 247, file=f)

Der Ausgabetext ist "Total: 247\n". print() wandelt seine Argumente um, trennt sie mit Leerzeichen und fügt standardmäßig ein abschließendes Zeilenumbruchzeichen hinzu.

writelines() nimmt eine Sequenz von Zeichenketten entgegen, fügt aber keine Zeilenabschlüsse ein. f.writelines(["a", "b"]) schreibt "ab". Um ein Element pro Zeile zu erhalten, nimm ein Zeilenumbruchzeichen in jede Zeichenkette auf oder füge die Zeichenketten mit "\n" zusammen und ergänze ein abschließendes Zeilenumbruchzeichen.

Bewahre frühere Durchläufe auf
with open("log.txt", "a", encoding="utf-8") as f:
    f.write("Program started\n")

Wenn zunächst keine Datei existiert, erzeugen zwei Durchläufe zwei Zeilen. Mit "w" würde jeder Durchlauf den früheren Eintrag ersetzen. Der Anfügemodus ergänzt kein fehlendes Zeilenumbruchzeichen: Endet der vorhandene Text mitten in einer Zeile, beginnt der neue Text unmittelbar danach.

Durchlaufe für einen Bericht Paare wie [("Ana", 92), ("Ben", 78)] und schreibe f"{name}: {score}\n". Die Formatierung geschieht vor dem Schreiben, daher erzeugt f"{82.333:.1f}" den Text "82.3". with schließt dann die Ausgabedatei und schreibt am Blockende den gepufferten Text.

Wichtige Erkenntnisse

  • "w" leert eine vorhandene Datei, sobald sie geöffnet wird.
  • "a" fügt am Ende hinzu; "x" verweigert das Ersetzen einer vorhandenen Datei.
  • write() nimmt eine Zeichenkette entgegen und fügt kein Zeilenumbruchzeichen hinzu.
  • print(..., file=f) wandelt Werte um und fügt standardmäßig ein Zeilenumbruchzeichen hinzu.
  • writelines() schreibt Zeichenketten nacheinander, ohne Trennzeichen hinzuzufügen.
  • Binärmodi lesen oder schreiben Bytes und nehmen kein Argument für die Zeichenkodierung entgegen.

1.4 Nützliche Zeilen finden und speichern

Viele Dateiaufgaben bestehen aus einer Schleife mit einer Entscheidung darin. Lies eine Zeile, entferne unerwünschte Leerraumzeichen, entscheide, ob sie relevant ist, und aktualisiere ein Ergebnis. Wenn du diese Schritte trennst, lässt sich ein Programm leichter prüfen.

Arbeite ein Protokoll durch

Angenommen, server.log enthält diese Einträge mit einer Leerzeile vor dem letzten:

2026-03-01 08:14 INFO Server started
2026-03-01 08:20 ERROR Disk almost full
2026-03-01 09:02 INFO User login: maya
2026-03-01 09:15 WARNING Slow response
2026-03-01 10:40 ERROR Database timeout

2026-03-01 11:05 INFO Backup finished

Jeder nicht leere Eintrag enthält ein Datum, eine Uhrzeit, eine Stufe und eine Meldung. Teile nur dreimal auf, damit die Meldung zusammenbleibt:

errors = 0
with open("server.log", encoding="utf-8") as f:
    for line in f:
        line = line.strip()
        if not line:
            continue
        parts = line.split(maxsplit=3)
        if parts[2] == "ERROR":
            errors += 1
            print(parts[3])
print(errors, "errors")

Beim zweiten Eintrag ist parts[2] "ERROR" und parts[3] ist "Disk almost full". Diese Meldung wird ausgegeben und der Zähler steigt auf 1. Der spätere Fehler erhöht ihn auf 2. Das Programm gibt beide Meldungen und danach „2 errors“ aus.

Prüfe den gewünschten Teil
PrüfungWas sie fragt
line.startswith("From:")Beginnt die Zeile mit diesem Text?
"ERROR" in lineKommt dieser Text irgendwo vor?
line.find("ERROR")Wo kommt er zum ersten Mal vor oder ist das Ergebnis -1?
parts[2] == "ERROR"Entspricht dieses Feld genau der Fehlerstufe?

Eine Suche an beliebiger Stelle würde auch „INFO No ERRORS today“ finden. Die Prüfung des Stufenfelds beantwortet die Frage zum Protokoll genauer.

Nach strip() ist eine Leerzeile ""; ihre Aufteilung ergibt []. Der Zugriff auf parts[2] würde dann IndexError auslösen. continue überspringt diese Zeile vor jedem Indexzugriff. Auch ein nicht leerer, aber unvollständiger Eintrag braucht eine Längenprüfung, wenn solche Einträge möglich sind.

Zähle Kategorien oder schreibe eine gefilterte Datei

Ein Wörterbuch enthält einen Zähler pro Stufe. Setze für jeden Eintrag level = parts[2] und dann counts[level] = counts.get(level, 0) + 1. Für das obige Protokoll sind die Zählerstände {'INFO': 3, 'ERROR': 2, 'WARNING': 1}. Der Standardwert 0 beginnt die Zählung einer Kategorie bei ihrem ersten Auftreten.

Um passende Einträge zu speichern, öffne in derselben with-Anweisung eine separate Zieldatei und schreibe eine Zeile, wenn ihre Stufe passt. Behalte die ursprüngliche line, wenn die Abstände wichtig sind; schreibst du bereinigten Text, füge das Zeilenumbruchzeichen wieder hinzu. Öffne die Quelldatei selbst niemals mit "w": Sie würde geleert, bevor das Lesen beginnt.

Mache unsichtbare Zeichen sichtbar

print(repr(line)) macht Leerzeichen und Zeilenumbruchzeichen am Ende sichtbar, zum Beispiel 'Disk full \n'. strip() entfernt beides, während rstrip("\n") die Leerzeichen behält. Beim normalen Lesen von Text werden erkannte Zeilenabschlüsse von Windows, Unix und alten Mac-Systemen in "\n" umgewandelt. Eine letzte Zeile ohne Abschluss bleibt ohne Abschluss. Ein mit input("File name: ").strip() eingelesener Dateiname lässt dieselbe Schleife mit verschiedenen Eingabedateien arbeiten.

Wichtige Erkenntnisse

  • Bereinige, wähle aus, verarbeite und gib Ergebnisse in getrennten Schritten aus.
  • Überspringe Leerzeilen, bevor du über einen Index auf aufgeteilte Felder zugreifst.
  • Prüfe das gewünschte Feld, wenn eine Suche in der ganzen Zeile zu viel finden könnte.
  • Verwende ein Wörterbuch, um pro Kategorie einen Zähler zu führen.
  • Schreibe gefilterte Ausgaben in eine andere Datei.
  • repr() zeigt Leerraumzeichen und Zeilenumbruchzeichen, die bei der normalen Ausgabe verborgen bleiben.
2

Dateien mithilfe von Pfaden finden

Ein korrekter Dateiname ist nur ein Teil einer Ortsangabe. Das Verzeichnis, in dem ein Programm startet, beeinflusst relative Pfade und kann sich von dem Verzeichnis unterscheiden, das das Skript enthält. Du verfolgst Pfade durch einen Verzeichnisbaum, vermeidest Escape-Sequenzen in Windows-Zeichenketten und erstellst Speicherorte mit pathlib. Diese Fähigkeiten helfen, Fehler durch fehlende Dateien zu erklären, und ermöglichen es demselben Projekt, seine Daten auf verschiedenen Computern zu finden und Ausgabeverzeichnisse vorzubereiten.

2.1 Wo Python nach einer Datei sucht

Ein Pfad beschreibt einen Ort in einem Verzeichnisbaum. Er kann an der Wurzel dieses Baums oder im aktuellen Arbeitsverzeichnis des Programms beginnen. Eine Datei kann auf dem Computer existieren und dennoch an dem Ort fehlen, den dein Programm angibt.

Lies einen Pfad von seinem Ausgangspunkt aus
ArtBeispielAusgangspunkt
Absolut, macOS oder Linux/Users/maya/data/notes.txtDie Wurzel /
Absolut, WindowsC:/Users/Maya/data/notes.txtDas Wurzelverzeichnis von Laufwerk C
Relativdata/notes.txtAktuelles Arbeitsverzeichnis

Angenommen, ein Verzeichnis namens project enthält die Verzeichnisse scripts und data. Du führst python scripts/report.py aus, während du in project arbeitest. Beim Öffnen von "data/notes.txt" wird in project/data gesucht, obwohl das Skript in project/scripts liegt.

Startest du dasselbe Skript stattdessen, während du in project/scripts arbeitest, verweist dieser relative Pfad auf einen Ort in project/scripts/data. Das Skript wurde nicht verschoben; der Ausgangspunkt hat sich geändert.

from pathlib import Path
print(Path.cwd())

Dies gibt das aktuelle Arbeitsverzeichnis aus. os.getcwd() nach import os liefert dieselbe Information als Zeichenkette. Editoren und Startprogramme können ein Arbeitsverzeichnis auswählen, prüfe es also, wenn der Ort unklar ist.

Bewege dich durch Verzeichnisse

In einem relativen Pfad bezeichnet . das aktuelle Verzeichnis und .. das übergeordnete Verzeichnis. Von project/scripts aus führt ../data/notes.txt hinauf zu project und dann hinunter nach data. Wenn du .. hinzufügst, ohne das Ausgangsverzeichnis zu prüfen, kann das Programm am falschen Ort suchen.

Ein absoluter Pfad ist nützlich, um einen bestimmten Ort eindeutig anzugeben, aber ein Pfad wie C:/Users/Maya/Desktop/data.csv bindet weitergegebenen Code an die Verzeichnisse einer Person. Verwende einen relativen Pfad mit klarem Ausgangspunkt oder erstelle den Pfad ausgehend vom eigenen Verzeichnis des Skripts, wenn die Daten dorthin gehören.

Erhalte umgekehrte Schrägstriche unter Windows

Windows zeigt zwischen Verzeichnissen häufig umgekehrte Schrägstriche an. In einer gewöhnlichen Python-Zeichenkette beginnt ein umgekehrter Schrägstrich eine Escape-Sequenz: \n wird zu einem Zeilenumbruchzeichen und \t zu einem Tabulatorzeichen. Das Literal "C:\new\table.txt" enthält daher nicht den beabsichtigten Pfad.

Diese Formen erhalten den beabsichtigten Pfad:

raw = r"C:\new\table.txt"
escaped = "C:\\new\\table.txt"
forward = "C:/new/table.txt"

Python unter Windows akzeptiert Schrägstriche. Eine rohe Zeichenkette verhindert, dass umgekehrte Schrägstriche zu Escape-Sequenzen werden, kann aber nicht mit einem einzelnen umgekehrten Schrägstrich enden. Zum Beispiel ist r"C:\data\" ungültige Syntax.

Prüfe Namen und Verzeichnis

Achte auf Unterschiede in der Schreibweise und verborgene Endungen: Eine als „notes.txt“ angezeigte Datei kann tatsächlich „notes.txt.txt“ heißen. Auch Groß- und Kleinschreibung ist wichtig. Linux unterscheidet üblicherweise Data.csv von data.csv; die üblichen Einstellungen von Windows und macOS tun das nicht. Wenn du die tatsächliche Groß- und Kleinschreibung übernimmst, bleibt ein Projekt auf verschiedenen Systemen nutzbar.

Wichtige Erkenntnisse

  • Relative Pfade beginnen im aktuellen Arbeitsverzeichnis.
  • Das Arbeitsverzeichnis kann sich vom Verzeichnis des Skripts unterscheiden.
  • . bleibt im aktuellen Verzeichnis; .. führt zum übergeordneten Verzeichnis.
  • Verwende für Windows-Pfade rohe Zeichenketten, doppelte umgekehrte Schrägstriche oder Schrägstriche.
  • Prüfe bei einer fehlenden Datei die genauen Namen, Endungen und die Groß- und Kleinschreibung.

2.2 Pfade mit pathlib erstellen

Das Standardmodul pathlib stellt einen Pfad als eigenes Objekt bereit. Mit einem Path kannst du Verzeichnisnamen zusammenfügen, einen Dateinamen untersuchen und gängige Dateioperationen ausführen, ohne Zeichenketten mit Trennzeichen von Hand zusammenzusetzen.

Zusammenfügen und untersuchen
from pathlib import Path
p = Path("reports") / "2026" / "sales.csv"
print(p.name)
print(p.stem)
print(p.suffix)
print(p.parent)

Die ersten drei Ergebnisse sind „sales.csv“, „sales“ und „.csv“. Das übergeordnete Verzeichnis ist der Pfad reports/2026, der mit dem Trennzeichen des Systems angezeigt wird. Hier fügt / Pfadteile zusammen; es dividiert keine Zahlen. Das ältere os.path.join() fügt ebenfalls Pfadteile als Zeichenketten zusammen.

Ein Path beschreibt einen Ort, selbst bevor dort etwas existiert. p.exists() prüft, ob an diesem Ort etwas existiert. p.is_file() und p.is_dir() unterscheiden eine Datei von einem Verzeichnis. Eine Existenzprüfung kann nicht garantieren, dass ein späteres Öffnen gelingt: Die Datei kann zwischen den Vorgängen verschwinden oder der Zugriff sich ändern. Behandle Fehler beim Öffnen, wenn das Programm darauf reagieren muss.

Lies oder schreibe eine kleine Datei

open() akzeptiert einen Path direkt. Für eine kleine Datei übernehmen diese Hilfsmethoden ebenfalls das Öffnen und Schließen:

p = Path("greeting.txt")
p.write_text("Hello\n", encoding="utf-8")
text = p.read_text(encoding="utf-8")

text wird zu "Hello\n". write_text() ersetzt vorhandenen Inhalt, genau wie das Öffnen mit "w"; die Methode hängt keinen Text an. read_text() lädt die ganze Datei, verwende also eine Dateischleife, wenn du eine große Datei Zeile für Zeile verarbeiten musst.

Gehe vom Verzeichnis des Skripts aus

Eine Datendatei, die neben einem Skript bereitgestellt wird, sollte ausgehend vom Skript gefunden werden, unabhängig vom Arbeitsverzeichnis:

base = Path(__file__).resolve().parent
scores_path = base / "data" / "scores.txt"
with open(scores_path, encoding="utf-8") as f:
    scores = f.readlines()

__file__ bezeichnet die Skriptdatei. resolve() macht ihren Pfad absolut und parent wählt das Verzeichnis aus, das sie enthält. In einer interaktiven Shell ist __file__ nicht definiert, daher gehört dieses Muster in ein Skript.

Finde Dateien und bereite Ausgabeverzeichnisse vor
for p in sorted(Path("logs").glob("*.txt")):
    text = p.read_text(encoding="utf-8")
    print(p.name, len(text.splitlines()))

glob("*.txt") wählt passende Pfade in logs aus. iterdir() liefert die Einträge des Verzeichnisses ohne diesen Musterfilter. Das Sortieren macht die Reihenfolge vorhersehbar. splitlines() zählt die Textzeilen, ohne den letzten Zeilenabschluss als zusätzliche Leerzeile zu behandeln.

Das Schreiben erstellt eine Datei, aber keine fehlenden übergeordneten Verzeichnisse. Bereite sie zuerst vor:

folder = Path("output") / "daily"
folder.mkdir(parents=True, exist_ok=True)
(folder / "report.txt").write_text("Ready\n", encoding="utf-8")

parents=True erstellt fehlende Verzeichnisse oberhalb von daily. exist_ok=True akzeptiert ein bereits vorhandenes Verzeichnis. Es wandelt eine vorhandene gewöhnliche Datei nicht in ein Verzeichnis um.

Wichtige Erkenntnisse

  • Path fügt Teile mit / zusammen und funktioniert direkt mit open().
  • name, stem, suffix und parent geben verschiedene Pfadteile an.
  • Eine Existenzprüfung kann nicht garantieren, dass ein späteres Öffnen gelingt.
  • read_text() liest den gesamten Text; write_text() ersetzt ihn.
  • Erstelle Pfade für Daten relativ zum Skript ausgehend von Path(__file__).resolve().parent.
  • Verwende glob(), um Treffer zu finden, und mkdir(), um fehlende Verzeichnisse zu erstellen.
3

CSV-Dateien lesen und schreiben

Tabellendaten brauchen mehr Struktur als eine Sammlung von Zeilen. Ein Name kann ein Komma enthalten, ein Feld einen Zeilenumbruch, und eine Mengenangabe kommt dennoch als Text an. Du verwendest das CSV-Modul, um diese Grenzen zu erhalten, Werte für Berechnungen umzuwandeln und Ergebnisse zu schreiben, die ein anderes Programm lesen kann. Benannte Spalten machen die Verarbeitung übersichtlicher, während Prüfungen der Kopfzeilen und Zeilenstruktur helfen, unvollständige Daten aufzudecken.

3.1 CSV-Zeilen und -Felder lesen

Eine CSV-Datei speichert eine Tabelle als Text. Ihre Datensätze sind Zeilen und ihre Felder sind Spaltenwerte. Felder werden häufig durch Kommas getrennt, aber Felder in Anführungszeichen können Kommas und sogar Zeilenumbrüche enthalten. Verwende das Modul csv, damit diese Werte zusammenbleiben.

Lass einen Leser Anführungszeichen behandeln
name,quiz1,quiz2
Ana,8,9
Ben,7,6
"Lopez, Maria",10,8

Die erste Zeile ist eine Kopfzeile mit Spaltennamen. Die letzte Datenzeile hat drei Felder, nicht vier: Das Komma innerhalb des Namens in Anführungszeichen gehört zum Namen. Ein doppeltes Anführungszeichen innerhalb eines Feldes in Anführungszeichen wird zweimal geschrieben. Würdest du jede Zeile mit split(",") aufteilen, würden diese Regeln ignoriert und der Name in Teile zerlegt.

import csv
with open("grades.csv", newline="", encoding="utf-8") as f:
    reader = csv.reader(f)
    header = next(reader)
    for row in reader:
        average = (int(row[1]) + int(row[2])) / 2
        print(row[0], average)

Der Leser gibt Listen von Zeichenketten zurück. next(reader) liest die Kopfzeile einmal ein, sodass die Schleife die Daten verarbeitet. Das Programm gibt „Ana 8.5“, „Ben 6.5“ und „Lopez, Maria 9.0“ aus. In der ersten Datenzeile ergibt die Umwandlung von "8" und "9" zusammen 17; die anschließende Division durch 2 ergibt 8,5.

Stimme Dateibehandlung und Tabellenverarbeitung aufeinander ab

Öffne CSV-Dateien mit newline="", damit das Modul csv die Zeilenabschlüsse selbst behandelt. Das ist wichtig, wenn ein Feld in Anführungszeichen einen Zeilenumbruch enthält. Ein CSV-Datensatz kann sich über mehrere physische Dateizeilen erstrecken, daher ersetzt das zeilenweise Aufteilen keinen CSV-Leser.

Standardmäßig belässt der Leser Werte als Zeichenketten. Ohne Umwandlung verkettet row[1] + row[2] die Zeichenketten "8" und "9" zu "89". Vergisst du dagegen, die Kopfzeile zu überspringen, wird versucht, "quiz1" umzuwandeln, und ValueError ausgelöst.

Wenn eine Datei leer sein könnte, liest next(reader, None) eine vorhandene Kopfzeile ein und gibt andernfalls None zurück. Eine vollständig leere CSV-Zeile wird zu []. Überspringe solche Zeilen vor dem Indexzugriff mit if not row: continue. Auch eine nicht leere Zeile mit zu wenigen Feldern braucht eine Längenprüfung; das bloße Überspringen leerer Zeilen schützt row[2] nicht vor jedem kurzen Datensatz.

Beachte das Format der Datei
reader = csv.reader(f, delimiter=";", skipinitialspace=True)

Dies wählt Semikolons als Trennzeichen und entfernt Leerzeichen unmittelbar danach. Wähle das Trennzeichen, das die Datei tatsächlich verwendet; eine Änderung des Trennzeichens wandelt Dezimalkommas nicht in Dezimalpunkte um. float("2,50") löst weiterhin ValueError aus.

Einige Exporte aus Tabellenkalkulationsprogrammen beginnen mit einer UTF-8-Byte-Reihenfolgemarkierung. Beim Lesen mit encoding="utf-8" kann "\ufeff" am Anfang des ersten Feldes stehen bleiben, sodass aus der Kopfzeile "name" "\ufeffname" wird. Für dieses Format entfernt encoding="utf-8-sig" die Markierung; damit lassen sich auch UTF-8-Dateien ohne Markierung lesen.

Wichtige Erkenntnisse

  • Ein CSV-Datensatz kann Kommas oder Zeilenumbrüche innerhalb von Anführungszeichen enthalten.
  • Verwende csv.reader statt einer einfachen Aufteilung an Kommas, um Anführungszeichen zu berücksichtigen.
  • Öffne CSV-Dateien mit newline="" und einer passenden Zeichenkodierung.
  • Der Standardleser gibt Zeichenketten zurück; überspringe eine Kopfzeile vor der Umwandlung in Zahlen.
  • Prüfe auf leere oder kurze Zeilen, bevor du auf Felder zugreifst.
  • Wähle das richtige Feldtrennzeichen und berücksichtige eine vorhandene Byte-Reihenfolgemarkierung.

3.2 Tabellenzeilen als CSV schreiben

Ein CSV-Schreiber wandelt Werte in korrekt getrennte und bei Bedarf in Anführungszeichen gesetzte Felder um. Übergib ihm Zeilen als Sequenzen von Werten und lass ihn die Satzzeichen behandeln. So vermeidest du Ausgaben, die richtig aussehen, bis ein Name oder eine Meldung ein Komma enthält.

Schreibe eine Kopfzeile und Daten
import csv
with open("summary.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(["name", "average"])
    writer.writerow(["Ana", 8.5])
    writer.writerow(["Lopez, Maria", 9.0])

Die Datei enthält die Zeilen name,average, Ana,8.5 und "Lopez, Maria",9.0. Der CSV-Schreiber wandelt Zahlen in Text um. Er setzt den Namen mit einem Komma in Anführungszeichen und verdoppelt jedes doppelte Anführungszeichen innerhalb eines Feldes in Anführungszeichen. None wird zu einem leeren Feld, sodass beim erneuten Lesen der Datei None nicht automatisch wiederhergestellt wird.

writerow() nimmt eine Zeile entgegen. writerows() nimmt eine Sequenz von Zeilen entgegen, etwa [["Ana", 8.5], ["Ben", 6.5]]. Übergibst du "Ana" direkt an writerow(), erhält die Methode stattdessen drei Zeichen und erzeugt A,n,a. Verwende ["Ana"] für eine Zeile mit einem Feld.

Überlasse CSV die Zeilenabschlüsse

Verwende newline="" beim Öffnen der Ausgabedatei. Der Standardschreiber beendet Datensätze mit "\r\n". Wird zusätzlich die Umwandlung von Zeilenabschlüssen im Textmodus zugelassen, kann Windows einen zusätzlichen Wagenrücklauf hinzufügen, der bei manchen Lesern unerwünschte Leerzeilen erzeugt. Das Argument newline verhindert diese zweite Umwandlung.

Wandle eine Datei in eine andere um
with open("grades.csv", newline="", encoding="utf-8") as src, open("summary.csv", "w", newline="", encoding="utf-8") as dst:
    reader = csv.reader(src)
    writer = csv.writer(dst)
    next(reader)
    writer.writerow(["name", "average"])
    for row in reader:
        average = (int(row[1]) + int(row[2])) / 2
        writer.writerow([row[0], round(average, 2)])

Für die Bewertungszeilen „Ana,8,9“, „Ben,7,6“ und "Lopez, Maria",10,8 sind die arithmetischen Mittel 8,5, 6,5 und 9,0. Der Leser entfernt die CSV-Anführungszeichen vom eingelesenen Feldwert; der Schreiber fügt die nötigen Anführungszeichen bei der Ausgabe wieder hinzu. round() bestimmt den geschriebenen Zahlenwert, erzwingt aber keine Anzeige von zwei Nachkommastellen. Verwende ein Format wie f"{average:.2f}", wenn genau zwei Stellen gewünscht sind.

Hänge Daten an, ohne die Kopfzeile zu wiederholen

Prüfe vor dem Öffnen einer Datei zum Anhängen, ob sie eine Kopfzeile braucht:

from pathlib import Path
p = Path("sales.csv")
needs_header = not p.exists() or p.stat().st_size == 0
with open(p, "a", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    if needs_header:
        writer.writerow(["item", "quantity"])
    writer.writerow(["coffee", 4])

Auch eine vorhandene leere Datei braucht ihre Kopfzeile. Wird die Kopfzeile bei jedem Durchlauf geschrieben, stehen Spaltennamen mitten in den Daten. Dieses Muster setzt voraus, dass ein Programm die Datei aktualisiert; eine Existenzprüfung verhindert nicht, dass andere Programme sie ändern.

Wichtige Erkenntnisse

  • Übergib eine Sequenz von Feldern an writerow() und Zeilen an writerows().
  • Der CSV-Schreiber wandelt Werte um und behandelt Anführungszeichen; None wird zu einem leeren Feld.
  • Verwende newline="" sowohl für die CSV-Ausgabe als auch für die Eingabe.
  • Schreibe eine Kopfzeile beim Anhängen nur, wenn die Datei neu oder leer ist.

3.3 Spaltennamen in CSV-Code verwenden

Positionsbasierter Code wie row[2] hängt von der Spaltenreihenfolge ab. Mit einem wörterbuchbasierten Leser kannst du den benötigten Wert benennen. Ein Wörterbuch ordnet Schlüsseln Werte zu; hier liefert die Kopfzeile die Schlüssel und jeder Datensatz deren Werte.

Lies Felder anhand ihres Namens
import csv
with open("inventory.csv", newline="", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    rows = list(reader)

Für die Kopfzeile product,stock,price und die Zeile notebook,12,2.50 ist das erste Wörterbuch {'product': 'notebook', 'stock': '12', 'price': '2.50'}. reader.fieldnames liefert die Namen aus der Kopfzeile. Die Kopfzeile wird automatisch eingelesen; ein Aufruf von next(reader) würde den ersten Datensatz überspringen.

Verwende row["stock"], um den Bestand auszuwählen, selbst wenn die Spalten neu angeordnet werden. Wandle ihn mit int() um, um Mengen zu vergleichen. Die Werte bleiben Zeichenketten; Spaltennamen verleihen dem Leser keine numerischen Datentypen.

Filtere und summiere

Angenommen, die Tabelle enthält 12 Notizbücher zum Preis von 2,50, 3 Stifte zu 1,20, 0 Hefter zu 7,95 und 25 Mappen zu 0,80.

low = [r for r in rows if int(r["stock"]) < 5]
value = sum(int(r["stock"]) * float(r["price"]) for r in rows)

low enthält die Zeilen für Stift und Hefter. Der Wert beträgt 53,6 €: Die Notizbücher tragen 30 bei, die Stifte 3,6, die Hefter 0 und die Mappen 20. Der Filter nutzt den Bestand, die Summe dagegen Bestand und Preis.

Unterscheide fehlende Schlüssel von fehlenden Werten

Die Namen in der Kopfzeile müssen genau übereinstimmen. Name und name sind verschiedene Schlüssel. Ein Leerzeichen nach einem Komma kann Teil eines Spaltennamens werden; skipinitialspace=True entfernt Leerzeichen unmittelbar nach Trennzeichen.

Eine Kopfzeile name,quiz1,quiz2 mit den Daten Ben,7 ergibt {'name': 'Ben', 'quiz1': '7', 'quiz2': None}. Der Schlüssel existiert, aber sein Wert fehlt. int(None) löst TypeError aus. Ein vorhandenes leeres Feld ist "", und seine Umwandlung löst ValueError aus. Ein Schlüssel, der in der Kopfzeile fehlt, verursacht beim Nachschlagen dagegen KeyError.

Bei den Daten Cara,1,2,3 werden zusätzliche Felder als None: ['3'] gesammelt; die benannten Felder enthalten weiterhin "Cara", "1" und "2". Prüfe die Struktur einer Zeile, wenn korrekte Summen von jedem Feld abhängen.

Schreibe ausgewählte Spalten
with open("reorder.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["product", "stock"])
    writer.writeheader()
    for r in low:
        writer.writerow({"product": r["product"], "stock": r["stock"]})

fieldnames legt die Ausgabereihenfolge unabhängig von der Wörterbuchreihenfolge fest. Fehlende Wörterbuchschlüssel werden zu leeren Feldern. Zusätzliche Schlüssel lösen standardmäßig ValueError aus: Die Übergabe eines Bestandswörterbuchs mit price an diesen Schreiber für zwei Spalten schlägt fehl. Erstelle wie gezeigt das kleinere Wörterbuch oder wähle extrasaction="ignore", wenn zusätzliche Felder absichtlich weggelassen werden sollen.

Wichtige Erkenntnisse

  • DictReader liest die Kopfzeile ein und gibt Wörterbücher mit Zeichenketten als Werten zurück.
  • Namen in der Kopfzeile müssen genau mit den Schlüsseln beim Nachschlagen übereinstimmen.
  • Ein fehlendes Feld erhält standardmäßig None; ein vorhandenes leeres Feld ist "".
  • Zusätzliche Felder werden standardmäßig unter dem Schlüssel None abgelegt.
  • DictWriter benötigt fieldnames, um die Spaltenreihenfolge festzulegen.
  • Fehlende Ausgabeschlüssel werden zu leeren Feldern; unerwartete Schlüssel lösen standardmäßig ValueError aus.
4

Fehler mit try und except behandeln

Dateinamen können falsch sein, der Zugriff kann verweigert werden und eine Zahlenspalte kann ein Wort enthalten. Eine Ausnahme markiert die Stelle, an der die normale Ausführung nicht fortgesetzt werden kann. Du liest Fehlerberichte, fängst erwartete Probleme ab und trennst die Verarbeitung im Erfolgsfall vom Aufräumen. Wenn du anschließend Fehler durch Funktionsaufrufe verfolgst, kannst du die Fehlerbehandlung dort platzieren, wo eine sinnvolle Entscheidung möglich ist, etwa einen Leseversuch zu wiederholen oder eine zurückgewiesene Zeile zu melden.

4.1 Einen Fehlerbericht verstehen

Eine Ausnahme ist ein Objekt, das ein Problem während der Ausführung signalisiert. Ihr Auslösen unterbricht den normalen Ablauf. Behandelt kein Ausnahmebehandler sie, beendet Python das Programm mit einem Traceback, einem Bericht über die Aufrufe, die zum Fehler geführt haben.

Beginne unten
def average(values):
    return sum(values) / len(values)

def report():
    scores = []
    print(average(scores))

report()

Der Traceback endet mit ZeroDivisionError: division by zero. Beginne dort: Der Typ nennt die Art des Problems und die Meldung liefert Einzelheiten. Der Eintrag unmittelbar darüber verweist auf die Division in average(). Frühere Einträge zeigen den Aufruf aus report() und den ursprünglichen Aufruf von report(). Die Liste ist leer, ihre Länge ist also 0. Die gemeldete fehlschlagende Zeile zeigt, wo das Problem auftritt; die frühere Zuweisung der leeren Liste erklärt, wie es entstand.

Wähle den passenden Typ
TypTypische Ursache
ValueErrorint("3.5"): eine Zeichenkette mit einem unzulässigen Wert
TypeErrorlen(5): eine Operation mit der falschen Objektart
ZeroDivisionErrorDivision durch null
IndexErrorLesen einer Listenposition, die nicht existiert
KeyErrorNachschlagen eines fehlenden Wörterbuchschlüssels
NameErrorVerwendung eines nicht definierten Namens
AttributeErrorZugriff auf ein Attribut, das ein Objekt nicht besitzt

int("abc") erhält einen erlaubten Eingabetyp, eine Zeichenkette, kann diesen Wert aber nicht als ganze Zahl deuten. "5" + 3 mischt dagegen für die Addition unverträgliche Datentypen. Eine Zeichenkette, die Ziffern enthält, ist weiterhin eine Zeichenkette.

Dateioperationen haben spezifischere Typen: FileNotFoundError für einen fehlenden Pfad, PermissionError für verweigerten Zugriff und FileExistsError beim Erstellen einer vorhandenen Datei mit "x". Das Öffnen eines Verzeichnisses als gewöhnliche Datei kann IsADirectoryError auslösen. Das Dekodieren von Bytes mit einer unpassenden Zeichenkodierung kann UnicodeDecodeError auslösen.

Verstehe den Stammbaum

Ausnahmeklassen bilden eine Hierarchie. Ein Behandler für eine übergeordnete Klasse kann ihre Unterklassen abfangen:

  • OSError ist der übergeordnete Typ häufiger Dateisystemfehler, darunter FileNotFoundError und PermissionError.
  • LookupError ist der übergeordnete Typ von IndexError und KeyError.
  • ArithmeticError ist der übergeordnete Typ von ZeroDivisionError.
  • UnicodeDecodeError gehört zu ValueError.

Diese Zweige stammen von Exception ab, das von BaseException abstammt. KeyboardInterrupt und SystemExit stammen dagegen direkt von BaseException ab. Durch diesen Unterschied lässt except Exception Benutzerunterbrechungen und Programmbeendigungen durch.

Unterscheide Syntax-, Laufzeit- und Logikprobleme

Ein fehlender Doppelpunkt oder eine fehlende schließende Klammer kann Python daran hindern, ein Skript einzulesen. Der entstehende SyntaxError tritt vor der Ausführung des Skripts auf, sodass ein try in demselben Skript ihn nicht abfangen kann. Eine Laufzeitausnahme tritt auf, während gültiger Code ausgeführt wird. Ein Logikfehler erzeugt ein falsches Ergebnis, ohne notwendigerweise eine Ausnahme auszulösen, etwa wenn eine Summe durch die falsche Anzahl dividiert wird.

Wichtige Erkenntnisse

  • Lies zuerst den Ausnahmetyp und die Meldung am Ende eines Tracebacks.
  • Verfolge anhand der Aufrufeinträge den Wert, der zum Fehler führt, bis zu seinem Ursprung zurück.
  • ValueError betrifft einen unzulässigen Wert; TypeError betrifft einen ungeeigneten Datentyp.
  • Ein Ausnahmebehandler für einen übergeordneten Typ fängt auch untergeordnete Ausnahmeklassen ab.
  • Syntax-, Laufzeit- und Logikfehler entstehen auf unterschiedliche Weise.

4.2 Ein Problem dort abfangen, wo es behandelt werden kann

Eine try-Anweisung führt fehleranfälligen Code aus und gibt ausgewählten Ausnahmen einen Behandlungspfad. Der Ausnahmebehandler sollte zu dem Problem passen, das das Programm erwartet und auf das es reagieren kann.

Verfolge den Ablauf
while True:
    try:
        age = int(input("Age: "))
        break
    except ValueError:
        print("Please enter a whole number, like 34.")
print("Next year you will be", age + 1)

Die Eingabe „twenty“ führt dazu, dass int() ValueError auslöst. Python überspringt den Rest des try, einschließlich break, und führt den passenden Behandler aus. Die Schleife fragt dann erneut. Bei der Eingabe „34“ wird das try durch break beendet, sodass das Programm die Schleife verlässt und „Next year you will be 35“ ausgibt.

Ein Ausnahmebehandler setzt die Ausführung nicht bei der fehlgeschlagenen Anweisung fort. Sie geht nach der try-Anweisung weiter, sofern der Behandler selbst diesen Ablauf nicht ändert. Passt kein Behandler, wird die Ausnahme nach außen weitergegeben.

Behandle unterschiedliche Fehler unterschiedlich
try:
    result = int(a) / int(b)
except ValueError:
    print("Both values must be whole numbers.")
except ZeroDivisionError:
    print("The second value cannot be 0.")

Eine fehlgeschlagene Umwandlung und ein Divisor null brauchen unterschiedliche Meldungen. Soll die Reaktion gleich sein, fasse die Typen in einem Tupel zusammen: except (ValueError, ZeroDivisionError):. Klammern funktionieren in allen Python-3-Versionen. Python 3.14 erlaubt auch eine Liste ohne Klammern, wenn kein as-Teil vorhanden ist; die Tupelform bleibt über Versionen hinweg klar.

Python prüft Klauseln von oben nach unten und führt die erste passende aus. Setze FileNotFoundError vor den übergeordneten Typ OSError, wenn eine fehlende Datei eine besondere Reaktion benötigt. In umgekehrter Reihenfolge ist der spezielle Behandler unerreichbar.

Nutze die Meldung, ohne andere Programmfehler zu verbergen
try:
    quantity = int(text)
except ValueError as err:
    print("Cannot read quantity:", err)

err ist das Ausnahmeobjekt; seine Ausgabe zeigt die Meldung. type(err).__name__ liefert seinen Klassennamen. Python löscht die Bindung von err, wenn der Behandler endet. Kopiere die Meldung daher innerhalb des Blocks in eine andere Variable, wenn sie später benötigt wird.

Halte das try klein. Setze spätere Berechnungen außerhalb des Behandlers für die Umwandlung, wenn ihre Fehler anders behandelt werden müssten. except Exception: kann Programmfehler wie eine nicht definierte Variable verbergen. Ein bloßes except: ist noch umfassender: Es fängt auch KeyboardInterrupt und SystemExit ab.

Wiederhole die Operation selbst

Die Prüfung mit text.isdigit() prüft nicht alles, was int() akzeptiert. "-5" und " 34" bestehen diese Prüfung nicht, lassen sich aber erfolgreich umwandeln; "²" besteht sie, lässt sich aber nicht mit int() umwandeln. Wenn du die Umwandlung versuchst und ValueError abfängst, gelten die Regeln der Umwandlung selbst.

Sorge bei der Behandlung fehlerhafter Daten für eine sichtbare oder protokollierte Reaktion. Ein leeres except ValueError: pass kann dazu führen, dass das Programm mit fehlenden Ergebnissen weiterläuft, ohne festzuhalten, was schiefgegangen ist.

Wichtige Erkenntnisse

  • Eine Ausnahme überspringt den verbleibenden try-Code und führt den ersten passenden Behandler aus.
  • Verwende spezifische Typen und setze Behandler für Unterklassen vor Behandler für übergeordnete Klassen.
  • Fasse Typen in einem Tupel zusammen, wenn ihre Behandlung gleich ist.
  • except ... as err ermöglicht innerhalb des Behandlers den Zugriff auf die Meldung.
  • Halte das try auf das Nötige beschränkt, damit Meldungen die tatsächlich fehlgeschlagene Operation beschreiben.
  • Versuche die Umwandlung in eine Zahl direkt, wenn du prüfen möchtest, was sie akzeptiert.

4.3 Erfolg, Aufräumen und Fehler zwischen Funktionen

Eine try-Anweisung kann die fehleranfällige Operation, die Fehlerbehandlung, die Verarbeitung im Erfolgsfall und das Aufräumen trennen. Eine Ausnahme kann auch eine Funktion verlassen und von ihrem aufrufenden Code behandelt werden.

Gib der Verarbeitung im Erfolgsfall einen eigenen Block
try:
    x = 10 / int(text)
except ValueError:
    print("not a number")
except ZeroDivisionError:
    print("zero")
else:
    print("result", x)
finally:
    print("done")

Bei text = "4" gibt das Programm „result 2.5“ und „done“ aus. Bei "abc" gibt es „not a number“ und „done“ aus; bei "0" gibt es „zero“ und „done“ aus.

else wird ausgeführt, wenn das try regulär und ohne Ausnahme endet. Es wird nicht ausgeführt, nachdem ein Behandler einen Fehler behandelt hat. Es wird auch übersprungen, wenn return, break oder continue das try vorzeitig verlässt. Innerhalb von else ausgelöste Fehler werden nicht von den vorherigen except-Klauseln dieser Anweisung abgefangen, sodass die Verarbeitung im Erfolgsfall nicht versehentlich dieselben Behandler wie die fehleranfällige Operation nutzt.

Lass das Aufräumen auf jedem Pfad beim Verlassen laufen

finally wird ausgeführt, wenn der Programmablauf die Anweisung verlässt: nach Erfolg, nach einer behandelten Ausnahme und bevor eine unbehandelte Ausnahme weitergegeben wird. Es wird auch ausgeführt, bevor eine ausstehende Rückgabe abgeschlossen wird.

def label():
    try:
        return "from try"
    finally:
        print("finally ran")

value = label()
print(value)

Dies gibt „finally ran“ und danach „from try“ aus. Die Rückgabe wartete, während das Aufräumen ausgeführt wurde. Bei Dateien sorgt with bereits für das Schließen, sodass ein manuelles Schließen in finally üblicherweise nicht nötig ist.

Setze keine Anweisung wie return, break oder continue, die den Ablauf verändert, in finally. Das Verlassen des Aufräumblocks auf diese Weise kann eine ausstehende Ausnahme verwerfen oder eine Rückgabe überschreiben. Python 3.14 und neuere Versionen geben für dieses Muster eine SyntaxWarning aus. Beschränke dich in diesem Block auf das Aufräumen.

Verfolge eine Ausnahme bis zum aufrufenden Code
def read_scores(path):
    with open(path, encoding="utf-8") as f:
        return [int(line) for line in f]

try:
    scores = read_scores("scores.txt")
except FileNotFoundError:
    print("The score file is missing.")

Schlägt das Öffnen fehl, hat read_scores() keinen Behandler, sodass FileNotFoundError an den Aufruf innerhalb des äußeren try weitergegeben wird. Der aufrufende Code behandelt ihn und gibt die Meldung aus. Ist eine Zeile keine ganze Zahl, nimmt ein ValueError denselben Weg, aber der Behandler für fehlende Dateien passt nicht dazu.

Wähle die Ebene, auf der eine sinnvolle Reaktion möglich ist

Eine Lesefunktion weiß möglicherweise, wie sie Daten erhält, aber nicht, ob eine fehlende Datei zu einem erneuten Versuch, einer übersprungenen Aufgabe oder einem kontrollierten Stopp führen soll. Wird die Ausnahme an den Teil des aufrufenden Codes weitergegeben, der mit dem Benutzer spricht, kann dort entschieden werden. Wird sie zu früh abgefangen und eine leere Liste zurückgegeben, kann der Unterschied zwischen einer leeren Datei und einem fehlgeschlagenen Lesevorgang verborgen bleiben.

Wichtige Erkenntnisse

  • else wird nur nach regulärer Beendigung des try-Blocks ausgeführt.
  • finally wird vor dem Verlassen ausgeführt, auch bei einer Rückgabe oder einer unbehandelten Ausnahme.
  • Eine Ausnahme in else liegt außerhalb der vorherigen Behandler dieser Anweisung.
  • Vermeide das Verlassen von finally auf eine Weise, die ausstehende Fehler oder Rückgaben verwerfen kann.
  • Unbehandelte Ausnahmen werden durch Aufrufe bis zu einem passenden äußeren Behandler weitergegeben.

4.4 Auf Datei- und Zeilenfehler reagieren

Ein Programm reagiert kontrolliert auf einen Fehler, wenn es auf ein Problem beherrscht und hilfreich antwortet. Es kann erneut fragen, eine übersprungene Zeile melden oder mit einer klaren Meldung stoppen. Wähle die Reaktion danach, wofür das Ergebnis verwendet wird.

Versuche es bei einer fehlenden Datei erneut
while True:
    name = input("File name: ").strip()
    try:
        with open(name, encoding="utf-8") as f:
            text = f.read()
    except FileNotFoundError:
        print(f"No file named '{name}'. Please try again.")
    else:
        break
print(len(text.splitlines()), "lines")

Ein fehlgeschlagenes Öffnen überspringt die Zuweisung und erreicht den Behandler. Die Schleife fragt erneut. Ein erfolgreicher Lesevorgang erreicht else, beendet die Schleife und lässt text für die abschließende Zählung verfügbar. Die Datei wird von with bei beiden Arten, den betretenen Block zu verlassen, geschlossen.

Verwende für verschiedene Dateiprobleme FileNotFoundError, dann PermissionError und anschließend einen allgemeinen OSError-Behandler, falls andere Dateisystemfehler eine Reaktion benötigen. Die spezifischen Klauseln müssen zuerst stehen. Das Dekodieren fehlerhafter Bytes ist ein anderes Problem; eine Meldung über einen fehlenden Pfad würde es nicht beschreiben.

Behandle jede Datenzeile einzeln

Angenommen, für eine schnelle Verkaufsübersicht stehen nach der Kopfzeile die CSV-Zeilen coffee,4, tea,two, muffin,3, cookie, und juice,5.

import csv
total = 0
skipped = 0
with open("sales.csv", newline="", encoding="utf-8") as f:
    reader = csv.reader(f)
    next(reader, None)
    for row in reader:
        try:
            if len(row) != 2:
                raise ValueError("expected two fields")
            quantity = int(row[1])
        except ValueError as err:
            skipped += 1
            print(f"sales.csv, ending line {reader.line_num}: {err}")
        else:
            total += quantity
print("Total:", total, "Skipped:", skipped)

Die gültigen Mengen ergeben zusammen 12. Das Wort „two“ und die leere Mengenangabe werden zurückgewiesen, sodass der Zähler für übersprungene Zeilen 2 beträgt. Die Zeilenprüfung macht auch eine unerwartete Feldanzahl vor dem Indexzugriff zu einem gemeldeten Datenfehler. Steht try innerhalb der Schleife, kann nach einem fehlgeschlagenen Datensatz der nächste verarbeitet werden; stünde die Schleife in einem einzigen try, würde sie beim ersten Fehler verlassen.

Melde Stellen genau

Bei den fünf einzeiligen Datensätzen enden die fehlerhaften Werte in den Dateizeilen 3 und 5. enumerate(reader, start=2) würde hier diesen Zeilennummern entsprechen, aber ein Zeilenumbruch innerhalb von Anführungszeichen lässt einen CSV-Datensatz mehr als eine Zeile umfassen. reader.line_num meldet, wie viele physische Zeilen der Leser eingelesen hat. Wenn du sie als Endzeile bezeichnest, bleiben Meldungen auch bei mehrzeiligen Datensätzen genau.

Entscheide, ob ein Teilergebnis akzeptabel ist

Eine schnelle Zählung zur ersten Erkundung kann gemeldete übersprungene Datensätze erlauben. Eine Finanz- oder Notensumme kann jeden Datensatz benötigen: Stoppe und bitte um korrigierte Daten, statt eine Teilsumme als vollständig auszugeben. Nenne Datei, Stelle und Problem, damit es behoben werden kann.

Nach import sys schreibt sys.exit("Could not open sales.csv") die Meldung auf die Fehlerausgabe und beendet das Programm mit Status 1. Es löst SystemExit aus, was except Exception nicht abfängt. Halte Behandler spezifisch, damit ein unabhängiger Programmfehler nicht fälschlich als Dateiproblem bezeichnet wird.

Wichtige Erkenntnisse

  • Wähle je nach Aufgabe zwischen erneutem Versuch, Überspringen und Stoppen.
  • Setze die Fehlerbehandlung auf Zeilenebene in die Schleife, um nach einer fehlerhaften Zeile fortzufahren.
  • Melde übersprungene Datensätze und kennzeichne Teilergebnisse klar.
  • CSV-Datensatznummern können sich von physischen Zeilennummern unterscheiden.
  • sys.exit(message) beendet das Programm mit einer Fehlermeldung und Status 1.
  • Verwende spezifische Behandler, damit die Meldung zum tatsächlichen Problem passt.
5

Eigene Ausnahmen auslösen

Funktionen brauchen eine klare Möglichkeit, Eingaben zu melden, die sie nicht verarbeiten können. Das Auslösen einer Ausnahme verhindert, dass eine fehlgeschlagene Operation ein irreführendes Ergebnis erzeugt, und lässt den aufrufenden Code eine Reaktion wählen. Du wählst aussagekräftige Typen und Meldungen, gibst einen vorhandenen Fehler weiter und erhältst seine Ursache, wenn du ihn umwandelst. Ein kurzes Klassenmuster gibt einem Programm einen eigenen Fehlertyp, wenn der aufrufende Code ein Problem von einem anderen unterscheiden muss.

5.1 Eingaben mit raise zurückweisen

Eine Funktion sollte signalisieren, wenn sie kein gültiges Ergebnis liefern kann. raise löst an dieser Stelle eine Ausnahme aus, sodass der ungültige Pfad nicht fortgesetzt werden kann, als wäre die Operation erfolgreich gewesen.

Prüfe vor dem Rechnen
def withdraw(balance, amount):
    if amount <= 0:
        raise ValueError(f"amount must be positive, got {amount}")
    if amount > balance:
        raise ValueError(f"amount {amount} is more than the balance {balance}")
    return balance - amount

withdraw(100, 30) gibt 70 zurück. withdraw(100, 150) löst einen Fehler zum Kontostand aus; withdraw(100, -5) löst einen Fehler zu einem nicht positiven Betrag aus. Keiner der fehlschlagenden Aufrufe erreicht die Subtraktion.

Eine ausgelöste Ausnahme folgt denselben Behandlungsregeln wie ein eingebauter Fehler. Fängt ein passender Behandler innerhalb der Funktion sie ab, kann die Ausführung dort weitergehen. Andernfalls verlässt die Ausnahme die Funktion und erreicht den aufrufenden Code. Wird kein Behandler gefunden, meldet Python einen Traceback.

Lass den aufrufenden Code die Reaktion wählen
balance = 100
amount = 150
try:
    balance = withdraw(balance, amount)
except ValueError as err:
    print(f"Cannot withdraw: {err}")

Die Funktion meldet, warum sie keine Auszahlung vornehmen kann. Der aufrufende Code entscheidet, eine Meldung anzuzeigen. Da der Funktionsaufruf vor der Rückgabe fehlschlägt, ersetzt die Zuweisung den alten Kontostand nicht durch ein Ergebnis. Ein anderer aufrufender Code könnte nach einem kleineren Betrag fragen oder eine Transaktion abbrechen, ohne die Funktion zu ändern.

Wird stattdessen innerhalb der Funktion eine Warnung ausgegeben und None zurückgegeben, kann der aufrufende Code einen ungültigen Wert in eine spätere Berechnung übernehmen. Das Auslösen einer Ausnahme hält den Fehler mit seiner Ursache verbunden und gibt dem aufrufenden Code einen eigenen Fehlerpfad.

Wähle einen aussagekräftigen Typ
ProblemPassender Typ
Richtige Art der Eingabe, unzulässiger WertValueError
Falsche Objektart für die OperationTypeError

Ein negativer Zahlenbetrag ist ein unzulässiger Wert. Eine Liste, die übergeben wird, wo eine Zahl nötig ist, hat einen ungeeigneten Datentyp. Der Ausnahmetyp ist Teil des Funktionsverhaltens: Aufrufender Code wählt damit Behandler aus. Wähle einen Typ nicht nur, weil er dir vertraut ist.

Schreibe eine hilfreiche Meldung

Eine Meldung sollte nennen, was erwartet und was erhalten wurde. f"age must be between 0 and 130, got {age}" weist auf eine Korrektur hin. Eine Meldung wie „Fehler“ gibt keine brauchbaren Einzelheiten. Beziehe die Meldung auf die fehlgeschlagene Operation; Code, der mit dem Benutzer spricht, kann den größeren Kontext ergänzen.

raise ValueError("amount must be positive") erstellt eine Ausnahme mit einer Meldung. raise ValueError ist ebenfalls gültig und erstellt eine ohne Meldung. Eine einfache Zeichenkette ist keine Ausnahme: raise "error" löst TypeError aus, weil ausgelöste Objekte von BaseException abstammen müssen.

Wichtige Erkenntnisse

  • Löse eine Ausnahme an der Stelle aus, an der eine Funktion nicht korrekt fortfahren kann.
  • Verwende ValueError für einen unzulässigen Wert und TypeError für einen ungeeigneten Datentyp.
  • Nenne in einer hilfreichen Meldung die erwartete Eingabe und den erhaltenen Wert.
  • Überlasse dem aufrufenden Code die Entscheidung, wie auf die fehlgeschlagene Operation reagiert wird.

5.2 Ausnahmen weitergeben und benennen

Manchmal bemerkt eine Funktion einen Fehler, kann ihn aber nicht vollständig behandeln. Sie muss möglicherweise denselben Fehler weitergeben, ihn in einen nützlicheren umwandeln oder einem bestimmten Programmproblem einen eigenen Ausnahmetyp geben.

Löse den aktuellen Fehler erneut aus
def read_text(path):
    try:
        with open(path, encoding="utf-8") as f:
            return f.read()
    except FileNotFoundError:
        print(f"Missing: {path}")
        raise

Das bloße raise innerhalb des Behandlers löst die aktuelle Ausnahme erneut aus. Würde nur eine Meldung ausgegeben, wäre der Behandler beendet und die Funktion würde None zurückgeben; das erneute Auslösen macht den fehlgeschlagenen Lesevorgang für den aufrufenden Code sichtbar. Ein bloßes raise benötigt eine aktive Ausnahme, die es erneut auslösen kann.

Wandle um und erhalte die Ursache
def read_price(row):
    try:
        text = row["price"]
    except KeyError as err:
        raise ValueError("row has no 'price' column") from err
    return float(text)

Ein fehlender Schlüssel wird zu einem ValueError mit einer Meldung über die Zeile. from err vermerkt den ursprünglichen KeyError als direkte Ursache. Der Traceback zeigt den ursprünglichen Fehler, die Verbindung zwischen beiden und den neuen Fehler. Der aufrufende Code kann den umgewandelten Typ behandeln, während bei der Fehlersuche die Ursache auf niedrigerer Ebene erhalten bleibt.

Dieser Behandler ist auf das Nachschlagen beschränkt. Ein vorhandener Wert wie "free" schlägt später bei float(text) mit einem eigenen ValueError fehl; er wird nicht fälschlich als fehlende Spalte gemeldet.

Definiere einen eigenen Typ
class InsufficientFundsError(ValueError):
    pass

Dieses Muster erstellt eine benutzerdefinierte Ausnahmeklasse. Der Name endet üblicherweise auf Error. Der Name in Klammern ist der übergeordnete Typ, daher ist diese Klasse eine Art von ValueError.

def withdraw(balance, amount):
    if amount > balance:
        raise InsufficientFundsError(
            f"balance {balance}, requested {amount}"
        )
    return balance - amount

try:
    withdraw(100, 150)
except InsufficientFundsError as err:
    print("Not enough money:", err)

Das Programm gibt „Not enough money: balance 100, requested 150“ aus. Der aufrufende Code kann unzureichendes Guthaben von einem anderen ungültigen Wert unterscheiden. Stünde ein ValueError-Behandler vor diesem spezifischen Behandler, würde der übergeordnete Typ die Ausnahme zuerst abfangen.

Wähle den übergeordneten Typ für die gewünschte Behandlung

Die Ableitung von ValueError ermöglicht sowohl einem spezifischen Behandler als auch einem allgemeineren Behandler für Wertfehler, den benutzerdefinierten Typ abzufangen. Die direkte Ableitung von Exception erstellt einen eigenen Zweig für gewöhnliche Fehler, sodass except ValueError ihn nicht abfangen würde. Ein benutzerdefinierter Typ ist nützlich, wenn der aufrufende Code eine eigene Reaktion benötigt; andernfalls genügen ein klarer eingebauter Typ und eine Meldung.

Wichtige Erkenntnisse

  • Ein bloßes raise in einem Behandler gibt die aktuelle Ausnahme weiter.
  • raise NewError(...) from err vermerkt den ursprünglichen Fehler als direkte Ursache.
  • Eine benutzerdefinierte Ausnahme gibt dem aufrufenden Code einen eigenen Problemtyp.
  • Die übergeordnete Klasse bestimmt, welche allgemeineren Behandler den benutzerdefinierten Fehler abfangen können.
  • Setze einen spezifischen benutzerdefinierten Behandler vor den Behandler seines übergeordneten Typs.

Dateien und Ausnahmen in Python: Beispiele

5 Interaktive Lektionen

1

Eine Textdatei in einen gefilterten Bericht umwandeln

13 Schritte
Lies Zeilen, wähle Dateimodi und speichere ausgewählte Datensätze, während klar bleibt, wann Dateien geöffnet sind.
  1. 1
    EinführungLesen, entscheiden, speichern

    Ein Supportprotokoll enthält ein Ereignis pro Zeile. Du möchtest eine neue Datei, die nur die Ereignisse enthält, die Aufmerksamkeit benötigen. Diese Aufgabe verbindet Lesen, Zeichenkettenprüfungen und Schreiben.

    Verfolge zuerst, wie eine Datei Text liefert. Erstelle dann den Filter in kleinen Schritten, halte Eingabe und Ausgabe getrennt und lass with beide Dateien schließen, wenn die Verarbeitung endet.

  2. 2
    ErklärungEine Datei liefert Zeichenketten

    Angenommen, events.txt enthält "INFO Ready\nERROR Queue full\n". Das Öffnen erstellt ein Dateiobjekt, keine Kopie des Textes.

    f.readline() gibt "INFO Ready\n" zurück. Ein zweiter Aufruf gibt "ERROR Queue full\n" zurück. Ein dritter gibt "" zurück, weil die Datei vollständig gelesen wurde. Das Zeilenumbruchzeichen bleibt an einer zurückgegebenen Zeile erhalten; auch Zahlentext bliebe Text, bis er ausdrücklich umgewandelt wird.

  3. 3
    HerausforderungWähle eine Lesemethode

    Ein Protokoll kann viel größer als der verfügbare Speicher sein. Du musst jede Zeile nur einmal prüfen. Wie solltest du es lesen und warum?

    ---reveal---

    Durchlaufe die geöffnete Datei direkt mit for line in f:. Das liefert jeweils eine Zeile, ohne zuerst eine Zeichenkette oder Liste für die ganze Datei zu benötigen. Ein Aufruf von read() oder readlines() würde den verbleibenden Inhalt in den Speicher laden.

  4. 4
    BeispielLies innerhalb des Blocks
    with open("events.txt", encoding="utf-8") as f:
        first = f.readline()
    print(first.rstrip("\n"))
    

    Das Lesen geschieht bei geöffneter Datei. Beim Verlassen des eingerückten Blocks wird sie geschlossen; die spätere Ausgabe verwendet die gespeicherte Zeichenkette. Deshalb kann eine Operation auf first danach stattfinden, ein weiteres f.readline() aber nicht.

  5. 5
    HerausforderungSage das Aufräumen nach einem Fehler voraus

    Angenommen, innerhalb dieses Dateiblocks löst int("oops") ValueError aus. Der umgebende Code hat keinen Behandler. Bleibt die Datei geöffnet und verbirgt with den Fehler?

    ---reveal---

    Die Datei wird geschlossen, wenn die Ausführung den betretenen Block verlässt. Der Fehler wird weiterhin weitergegeben und erzeugt einen Traceback, wenn nichts ihn abfängt. Das automatische Aufräumen sorgt dafür, dass die Datei nicht geöffnet bleibt; zur Fehlerbehandlung wäre ein except-Behandler nötig.

  6. 6
    ErklärungWähle das Verhalten der Ausgabe

    Der gefilterte Bericht soll einen älteren Bericht ersetzen, öffne daher einen anderen Ausgabepfad mit "w". Dieser Modus leert eine vorhandene Datei sofort.

    Verwende für ein Aktivitätenprotokoll, das frühere Durchläufe behält, "a". Muss ein vorhandener Bericht vor dem Ersetzen geschützt werden, verwende "x" und behandle FileExistsError. Zum Erstellen der Datei müssen die enthaltenden Verzeichnisse weiterhin existieren.

  7. 7
    BeispielSchreibe genau eine Zeile

    Um eine ausgewählte Zeile zu schreiben, behalte ihren ursprünglichen Zeilenabschluss:

    dst.write(line)
    

    Hast du sie stattdessen mit strip() bereinigt, füge den Abschluss wieder hinzu:

    dst.write(cleaned + "\n")
    

    write() fügt kein Trennzeichen hinzu. print(cleaned, file=dst) ist eine weitere Möglichkeit, ein Zeilenumbruchzeichen hinzuzufügen, während bei writelines() die übergebenen Zeichenketten alle benötigten Zeilenabschlüsse enthalten müssen.

  8. 8
    HerausforderungSage das Ergebnis zweier Durchläufe voraus

    Ein Programm wird zweimal ausgeführt; zu Beginn existiert die Datei nicht. Jeder Durchlauf öffnet "runs.txt" im Anfügemodus und ruft f.write("OK") auf. Welcher Text wird gespeichert?

    ---reveal---

    Die Datei enthält "OKOK". Der Anfügemodus behält den ersten Durchlauf, aber weder der Modus noch write() fügt ein Zeilenumbruchzeichen hinzu. Würde stattdessen "OK\n" geschrieben, entstünde eine Zeile pro Durchlauf. Das Öffnen mit "w" würde nur das letzte "OK" übrig lassen.

  9. 9
    BeispielBereinige vor der Auswahl

    Unser Protokoll verwendet das erste Wort als Stufe. Beginne jeden Durchlauf mit:

    cleaned = line.strip()
    if not cleaned:
        continue
    level = cleaned.split(maxsplit=1)[0]
    

    Die Prüfung auf leere Zeilen verhindert den Indexzugriff auf eine leere Liste. Wenn du die ursprüngliche line separat behältst, kann die Ausgabe ihre Abstände erhalten. Nur die bereinigte Kopie wird verwendet, um die Stufe zu bestimmen.

  10. 10
    HerausforderungPrüfe den richtigen Teil

    Das Protokoll enthält „INFO ERROR counter reset“ und „ERROR Queue full“. Welche Prüfung der Stufe speichert nur den zweiten Eintrag?

    ---reveal---

    Prüfe level == "ERROR", nachdem du das erste Wort herausgelöst hast. Eine Suche nach "ERROR" an beliebiger Stelle würde auch den Informationseintrag speichern, weil das Wort in seiner Meldung vorkommt. Das Format zeigt dir, wo du die Kategorie für deine Auswahl findest.

  11. 11
    BeispielSetze den Filter zusammen
    count = 0
    with open("events.txt", encoding="utf-8") as src, open("urgent.txt", "w", encoding="utf-8") as dst:
        for line in src:
            cleaned = line.strip()
            if not cleaned:
                continue
            if cleaned.split(maxsplit=1)[0] == "ERROR":
                dst.write(line)
                count += 1
    print(count, "saved")
    

    Der Zähler ändert sich nur, wenn ein Eintrag geschrieben wird. Beide Dateien werden geschlossen, bevor der Zählerstand ausgegeben wird.

  12. 12
    HerausforderungUntersuche eine verlorene Quelldatei

    Jemand ändert den Ausgabenamen in "events.txt" und behält "w" bei. Warum besteht nun das Risiko, dass der Filter nichts speichert, obwohl die Quelldatei zuerst geöffnet wurde?

    ---reveal---

    Das zweite Öffnen leert dieselbe zugrunde liegende Datei, bevor die Schleife sie liest. Das erste Dateiobjekt hat keine separate Kopie des alten Textes gespeichert. Stelle wieder einen anderen Ausgabepfad ein, damit die Umwandlung ihre Eingabe beim Öffnen nicht löschen kann.

  13. 13
    ZusammenfassungVerfolge eine Dateiaufgabe vor der Ausführung

    Verfolge bei einer Dateiumwandlung vier Entscheidungen: woher die Eingabe kommt, wie viel Text auf einmal gelesen wird, wodurch ein Datensatz ausgewählt wird und was das Öffnen der Ausgabedatei mit vorhandenen Daten macht.

    Prüfe dann die Blockgrenzen. Dateioperationen benötigen offene Dateiobjekte; gespeicherte Zeichenketten, Listen und Summen können nach dem Schließen verwendet werden.

2

Projektdaten von jedem Startverzeichnis aus finden

9 Schritte
Verfolge relative Pfade, erstelle Pfade relativ zum Skript und bereite Verzeichnisse mit pathlib vor.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungFinde das Startverzeichnis
  2. 2
    BeispielVerfolge einen Start
  3. 3
    HerausforderungÄndere das Startverzeichnis
  4. 4
    TippPrüfe, bevor du den Pfad änderst
  5. 5
    BeispielErstelle den Pfad ausgehend vom Skript
  6. 6
    ErklärungBereite ein Ziel vor
  7. 7
    HerausforderungUntersuche einen Namen und finde Treffer
  8. 8
    HerausforderungPrüfe einen Lösungsvorschlag
  9. 9
    ZusammenfassungUnterscheide Ort und Verfügbarkeit
3

Eine Tabelle lesen und einen Bericht mit benannten Spalten schreiben

13 Schritte
Lies CSV mit Feldern in Anführungszeichen, wandle Zahlenfelder um und exportiere ausgewählte Spalten in einer festgelegten Reihenfolge.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungErhalte die Tabellenstruktur
  2. 2
    BeispielLies einen Datensatz mit Anführungszeichen
  3. 3
    BeispielÖffne und wandle um
  4. 4
    HerausforderungErkenne eine kurze Zeile
  5. 5
    BeispielSchreibe Werte als Felder
  6. 6
    HerausforderungHalte ein Feld zusammen
  7. 7
    ErklärungVerwende die Kopfzeile als Schlüssel
  8. 8
    BeispielFiltere nach Bestand
  9. 9
    HerausforderungUnterscheide fehlend und leer
  10. 10
    BeispielExportiere ausgewählte Spalten
  11. 11
    HerausforderungHänge später weitere Daten an
  12. 12
    TippWähle passende Trennzeichen und Zeichenkodierungen
  13. 13
    ZusammenfassungPrüfe Struktur und Bedeutung
4

Einen Fehler von einer fehlerhaften Zeile bis zu einer hilfreichen Reaktion verfolgen

15 Schritte
Lies einen Traceback, wähle Behandler und unterscheide einen erneuten Dateiversuch von der Fehlerbehandlung innerhalb einer Zeilenschleife.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungEntscheide, wo eine Fehlerbehandlung möglich ist
  2. 2
    BeispielBeginne mit dem Ausnahmetyp
  3. 3
    HerausforderungErkenne einen anderen Fehler
  4. 4
    BeispielFange nur den erwarteten Umwandlungsfehler ab
  5. 5
    HerausforderungOrdne verwandte Behandler
  6. 6
    ErklärungTrenne die Aufgaben bei Erfolg und beim Aufräumen
  7. 7
    HerausforderungVerfolge einen nicht abgefangenen Fehler
  8. 8
    VerbindungLass den aufrufenden Code entscheiden
  9. 9
    BeispielBehandle Fehler innerhalb der Datensatzschleife
  10. 10
    BeispielVerfolge drei Datensätze
  11. 11
    HerausforderungÄndere die Schleifengrenze
  12. 12
    TippBenenne die Stelle richtig
  13. 13
    HerausforderungEntscheide dich für ein vollständiges Ergebnis
  14. 14
    BeispielBeende das Programm mit einem Fehlerstatus
  15. 15
    ZusammenfassungPlatziere jede Reaktion auf der richtigen Ebene
5

Das Fehlerverhalten einer Funktion gestalten

10 Schritte
Prüfe eine Anfrage, löse hilfreiche Fehler aus und erhalte Unterschiede und Ursachen für den aufrufenden Code.

Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.

  1. 1
    EinführungGib Fehlern einen klaren Pfad
  2. 2
    BeispielWeise ungültige Anfragen zurück
  3. 3
    HerausforderungVerfolge eine fehlgeschlagene Zuweisung
  4. 4
    ErklärungWähle den zum Problem passenden Typ
  5. 5
    BeispielBenenne einen gesonderten Platzmangel
  6. 6
    HerausforderungHalte die spezifische Reaktion erreichbar
  7. 7
    BeispielReagiere und gib den Fehler weiter
  8. 8
    BeispielWandle einen Fehler auf niedrigerer Ebene um
  9. 9
    HerausforderungWähle die richtige Beziehung
  10. 10
    ZusammenfassungGestalte den Fehler für den aufrufenden Code aussagekräftig

Dateien und Ausnahmen in Python: Übungsaufgaben

50 Übungsfragen in 5 Sets

Set 1: Dateien lesen und kleine Programme nachvollziehen10 Übungsfragen

Frage 1 von 10

Eine Datei enthält "oak\npine". Was gibt f.readline() unmittelbar nach dem Öffnen zum Lesen zurück?
  1. "oak"
  2. ["oak\n", "pine"]
  3. "oak\n"
  4. "oak\npine"
Antwort zeigenAntwort ausblenden
Antwort: C
readline() gibt die nächste Zeile als Zeichenkette zurück und behält ihren Zeilenabschluss, sodass das Ergebnis "oak\n" ist. Es entfernt das Zeilenumbruchzeichen nicht, wie strip() es tun würde. Die zweite Zeile hat kein abschließendes Zeilenumbruchzeichen, aber das ändert die erste Zeile nicht.

Frage 2 von 10

Der Block endet regulär. Was wird ausgegeben?

with open("memo.txt", encoding="utf-8") as f:
    text = f.read()
print(f.closed)
  1. False
  2. True
  3. None
  4. text
Antwort zeigenAntwort ausblenden
Antwort: B
Das Verlassen des with-Blocks schließt die Datei, daher ist f.closed True. Der Name verweist weiterhin auf das Dateiobjekt; das Schließen löscht es nicht. Die gespeicherte Zeichenkette text bleibt verwendbar, aber die Datei kann über dieses geschlossene Objekt nicht erneut gelesen werden.

Frage 3 von 10

Ein Programm soll einem Protokoll eine Meldung über einen Durchlauf hinzufügen und dabei alle früheren Meldungen erhalten. Welchen Textdateimodus sollte es verwenden?
  1. "a"
  2. "w"
  3. "r"
  4. "x"
Antwort zeigenAntwort ausblenden
Antwort: A
Der Anfügemodus "a" schreibt am Ende und behält vorhandenen Text. Der Schreibmodus "w" würde das Protokoll beim Öffnen sofort leeren. Der Anfügemodus kann auch ein fehlendes Protokoll erstellen, aber das Programm muss weiterhin jedes benötigte Zeilenumbruchzeichen in seine Meldung aufnehmen.

Frage 4 von 10

Ein Terminal arbeitet in /work/lab. Es führt python tools/count.py aus, das "inputs/list.txt" öffnet. Welchen absoluten Ort bezeichnet dieser relative Pfad?
  1. /work/lab/tools/inputs/list.txt
  2. /work/inputs/list.txt
  3. /inputs/list.txt
  4. /work/lab/inputs/list.txt
Antwort zeigenAntwort ausblenden
Antwort: D
Der relative Pfad beginnt bei /work/lab und bezeichnet daher /work/lab/inputs/list.txt. Das Ausführen eines Skripts in tools ändert das Arbeitsverzeichnis nicht automatisch zu diesem Verzeichnis. Der Skriptort und das Arbeitsverzeichnis des Prozesses sind verschiedene Ausgangspunkte.

Frage 5 von 10

Was ist für p = Path("exports/week/report.csv") der Wert von p.stem?
  1. ".csv"
  2. "report"
  3. "report.csv"
  4. "exports/week"
Antwort zeigenAntwort ausblenden
Antwort: B
Der Dateiname ohne letzte Endung ist der letzte Name ohne sein letztes Suffix und ergibt "report". Die Eigenschaft name würde das Suffix behalten und "report.csv" ergeben. Das übergeordnete Verzeichnis bezeichnet das enthaltende Verzeichnis, während das Suffix die letzte Endung bezeichnet.

Frage 6 von 10

Welche Liste wird mit dem standardmäßigen csv.reader aus dem Datensatz "River, West",6,8 gelesen?
  1. ['River, West', '6', '8']
  2. ['River, West', 6, 8]
  3. ['\"River', ' West\"', '6', '8']
  4. ['River', 'West', '6', '8']
Antwort zeigenAntwort ausblenden
Antwort: A
Das Komma innerhalb der Anführungszeichen ist Teil eines Feldes, daher gibt der Leser drei Zeichenketten zurück: den Ortsnamen und zwei Zahlentexte. In seinen Standardeinstellungen wandelt er die Ziffern nicht in Zahlen um. Eine Aufteilung an jedem Komma würde den Ortsnamen fälschlich zerlegen.

Frage 7 von 10

Welche Zeile erzeugt writer.writerow("Leo") mit dem standardmäßigen Komma als Feldtrennzeichen?
  1. Leo
  2. "Leo"
  3. L,e,o
  4. L e o
Antwort zeigenAntwort ausblenden
Antwort: C
Eine Zeichenkette ist eine Sequenz von Zeichen, daher behandelt writerow("Leo") jedes Zeichen als Feld und schreibt L,e,o. Übergib für ein einzelnes Feld mit dem Namen ["Leo"]. Der CSV-Schreiber erwartet eine Sequenz von Feldwerten, keine einzelne unverpackte Zeichenkette.

Frage 8 von 10

Ein CSV-Mengenfeld enthält die Zeichenkette "many". Welche Ausnahme löst int(row["quantity"]) aus?
  1. TypeError
  2. KeyError
  3. IndexError
  4. ValueError
Antwort zeigenAntwort ausblenden
Antwort: D
Das Nachschlagen gelingt und liefert eine Zeichenkette, aber "many" ist keine gültige Darstellung einer ganzen Zahl, daher löst die Umwandlung ValueError aus. TypeError würde einen ungeeigneten Eingabetyp wie None beschreiben. Das angegebene Feld schließt hier einen Fehler durch einen fehlenden Schlüssel aus.

Frage 9 von 10

Was wird ausgegeben?

def read_count(text):
    return 12 / int(text)
try:
    result = read_count("0")
    print("read")
except ValueError:
    print("bad text")
except ZeroDivisionError:
    print("zero")
print("end")
  1. „read“, dann „end“
  2. „bad text“, dann „end“
  3. „zero“, dann „end“
  4. „zero“, dann „read“
Antwort zeigenAntwort ausblenden
Antwort: C
Die Zeichenkette „0“ wird erfolgreich umgewandelt, aber die Division in der Hilfsfunktion löst ZeroDivisionError aus. Die Ausnahme wird an den aufrufenden Code weitergegeben, überspringt den Rest des try-Blocks und erreicht den passenden Behandler, der „zero“ ausgibt. Danach wird „end“ ausgegeben; eine gültige Zahlenzeichenkette löst den Behandler für Umwandlungsfehler nicht aus.

Frage 10 von 10

Eine Funktion akzeptiert eine ganzzahlige Seitenzahl, kann aber keine Anzahl unter 1 verarbeiten. Welche Ausnahme und Meldung passen für die Eingabe -2?
  1. TypeError("pages must be positive, got -2")
  2. ValueError("pages must be positive, got -2")
  3. IndexError("pages must be positive, got -2")
  4. NameError("pages must be positive, got -2")
Antwort zeigenAntwort ausblenden
Antwort: B
Die Eingabe ist bereits eine ganze Zahl, ihr Datentyp ist also zulässig, aber ihr Wert verletzt die Anforderung. ValueError beschreibt dieses Problem und die Meldung nennt den erwarteten Bereich und den erhaltenen Wert. TypeError würde die Art der Eingabe falsch beschreiben.
Set 2: Methoden wählen und erwartete Fehler behandeln10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Ein Protokoll enthält die Zeilen "09:10 INFO ERROR count reset" und "09:12 ERROR Network down". Die Stufe ist das zweite durch Leerraumzeichen getrennte Feld. Welche Bedingung wählt nur Einträge der Fehlerstufe aus?
  1. "ERROR" in line
  2. line.startswith("ERROR")
  3. line.split()[2] == "ERROR"
  4. line.split()[1] == "ERROR"
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Eine Datei enthält "12\n15\n". Welches Paar ergibt sich aus first = f.read() gefolgt von second = f.read() auf einem frisch geöffneten Leser?
  1. first == "12\n15\n", second == ""
  2. first == "12\n", second == "15\n"
  3. first == "12\n15\n", second == first
  4. first == [12, 15], second == []
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Warum kann das Python-Zeichenkettenliteral "C:\new\tasks.txt" unter Windows die beabsichtigte Datei verfehlen?
  1. Der Laufwerksname macht dies zu einem laufwerksrelativen Pfad.
  2. Umgekehrte Schrägstriche funktionieren nur in relativen Pfaden.
  3. Die umgekehrten Schrägstriche leiten Zeilenumbruch und Tabulator ein.
  4. Ein absoluter Pfad muss mit einem Schrägstrich beginnen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Eine Datei beginnt mit city,visitors und Mesa,24. Nach reader = csv.DictReader(f) ruft das Programm einmal next(reader) auf und startet dann eine Schleife. Warum fehlt Mesa in dieser Schleife?
  1. Der Leser behandelt Zahlenwerte als Feldnamen.
  2. Der Aufruf hat den ersten Datensatz eingelesen.
  3. Der Leser kann keine kleingeschriebene Kopfzeile nutzen.
  4. Die Schleife überspringt Datensätze ohne Namen in Anführungszeichen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Die erste Zeile lautet label;count, aber der standardmäßige CSV-Leser gibt ["label;count"] zurück. Welche Lesereinstellung passt zu dieser Datei?
  1. skipinitialspace=True
  2. delimiter=","
  3. quoting=csv.QUOTE_ALL
  4. delimiter=";"
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Was wird ausgegeben?

try:
    value = 18 / int("0")
except ZeroDivisionError:
    print("zero")
else:
    print("success")
finally:
    print("closed")
  1. „success“, dann „closed“
  2. „zero“, dann „closed“
  3. „zero“, dann „success“
  4. „closed“, dann „zero“
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Eine vollständige Summe von Förderzahlungen wird benötigt. Eine CSV-Datei enthält einen ungültigen Betrag unter 200 Datensätzen. Warum ist es eine schlechte Fehlerbehandlung, ihn zu überspringen und den Rest als vollständige Summe anzuzeigen?
  1. Die Summe lässt eine benötigte Zahlung aus, ohne dies zu sagen.
  2. Ein Umwandlungsfehler verhindert das erneute Öffnen der Datei.
  3. Das Überspringen ändert alle verbleibenden Zahlungsbeträge.
  4. Eine CSV-Datei kann keine gültigen und ungültigen Zeilen enthalten.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

In einem try tritt FileNotFoundError auf. Der erste Behandler ist except OSError: print("file problem"), der zweite ist except FileNotFoundError: print("missing"). Was wird ausgegeben?
  1. „missing“
  2. „file problem“, dann „missing“
  3. „file problem“
  4. Kein Behandler passt.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Welche Anweisung gibt innerhalb eines except ValueError:-Blocks dieselbe aktive Ausnahme an den aufrufenden Code weiter?
  1. return
  2. raise
  3. continue
  4. pass
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Was wird ausgegeben?

def reserve(n):
    if n <= 0:
        raise ValueError("positive count required")
    return n * 2
result = 7
try:
    result = reserve(0)
except ValueError:
    print(result)
  1. 7
  2. 0
  3. None
  4. 14
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 3: Dateien und Fehlerbehandlungspfade durcharbeiten10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Eine Datei enthält nur „bad“. Was wird ausgegeben?

try:
    with open("one.txt", encoding="utf-8") as f:
        value = int(f.readline())
except ValueError:
    print(f.closed)
  1. False
  2. True
  3. Ein NameError-Traceback.
  4. Ein FileNotFoundError-Traceback.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Eine neue Datei wird mit f.writelines(["red", "blue\n"]) beschrieben und dann erneut im Anfügemodus geöffnet, um "green\n" zu schreiben. Welchen Text enthält sie?
  1. "redblue\ngreen\n"
  2. "red\nblue\ngreen\n"
  3. "green\n"
  4. "redbluegreen\n"
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Die Verzeichnisse results und results/daily fehlen. Was sollte ausgeführt werden, bevor mit Path("results/daily/run.txt").write_text("ok", encoding="utf-8") geschrieben wird?
  1. Path("results/daily").mkdir(exist_ok=True)
  2. Path("results/daily/run.txt").mkdir(parents=True)
  3. Path("results/daily").exists()
  4. Path("results/daily").mkdir(parents=True, exist_ok=True)
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Ein Programm zum Anhängen schreibt eine Kopfzeile nur, wenn not p.exists() gilt. Unter dem Pfad existiert eine Datei, sie hat aber null Bytes. Welche Bedingung gibt auch dieser Datei die benötigte Kopfzeile?
  1. p.exists() and p.stat().st_size > 0
  2. not p.exists() and p.stat().st_size == 0
  3. not p.exists() or p.stat().st_size == 0
  4. p.exists()
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Ein standardmäßiger DictReader hat die Kopfzeile name,first,second und liest Inez,5. Welcher Wert wird unter "second" gespeichert und was geschieht, wenn er an int() übergeben wird?
  1. None; löst TypeError aus.
  2. ""; löst ValueError aus.
  3. "5"; gibt 5 zurück.
  4. Kein Schlüssel; löst KeyError aus.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Welche Ausnahme löst das Nachschlagen im Wörterbuch {"east": 4}["west"] aus?
  1. IndexError
  2. ValueError
  3. KeyError
  4. NameError
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Was erhält der aufrufende Code und was wird zuerst ausgegeben?

def choose():
    try:
        return 11
    finally:
        print("leaving")
x = choose()
  1. Erhält None; zuerst erscheint „leaving“.
  2. Erhält 11; es erscheint keine Ausgabe.
  3. Erhält „leaving“; zuerst erscheint 11.
  4. Erhält 11; zuerst erscheint „leaving“.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Eine CSV-Zusammenfassung soll fehlerhafte Zahlenzeilen melden und mit späteren Datensätzen fortfahren. Wo sollte das try/except ValueError für die Umwandlung stehen?
  1. Um die gesamte Schleife, außerhalb ihres Blocks.
  2. Innerhalb der Schleife, um jede Zeilenumwandlung.
  3. Nach der Schleife, um die abschließende Ausgabe.
  4. Nur um den anfänglichen Aufruf von open().
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Bei class LimitError(ValueError): pass wird ein LimitError ausgelöst. Was geschieht, wenn except ValueError: vor except LimitError: steht?
  1. Keine der Klauseln passt zum benutzerdefinierten Typ.
  2. Nur der ValueError-Behandler wird ausgeführt.
  3. Beide Behandler werden in der angegebenen Reihenfolge ausgeführt.
  4. Nur der LimitError-Behandler wird ausgeführt.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Nach dem Entfernen von Randzeichen und dem Überspringen von Leerzeilen setzt ein Parser parts = line.split(maxsplit=2). Datensätze sollen ein Datum, eine Stufe und eine Meldung enthalten, manche enthalten aber nur ein Datum. Welche Prüfung muss parts[1] und parts[2] vorausgehen?
  1. len(parts) == 3
  2. line.endswith("\n")
  3. len(line) > 3
  4. " " in parts[0]
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 4: Unvollständige Daten und irreführende Behandler untersuchen10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Was gibt f.readline() am Dateiende zurück?
  1. None
  2. "\n"
  3. []
  4. ""
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

data.txt enthält drei Datensätze. Ein Programm öffnet die Datei mit "r", öffnet dann denselben Pfad mit "w" und beginnt erst danach, über das erste Dateiobjekt zu lesen. Warum besteht dabei das Risiko, die Eingabe zu verlieren?
  1. Der Lesemodus entfernt vor dem Schreiben das letzte Zeilenumbruchzeichen.
  2. Das erste Dateiobjekt wird automatisch zu einem Anfügeobjekt.
  3. Das Öffnen zum Schreiben leert die Datei vor Beginn des Lesens.
  4. Das Schreibobjekt kopiert jede Zeile, bevor es sie ersetzt.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

p.exists() gibt True zurück, aber die Datei wird vor open(p, encoding="utf-8") entfernt. Was benötigt ein robustes Programm beim Öffnen weiterhin?
  1. Einen Behandler für fehlende Dateien mit einer hilfreichen Reaktion.
  2. Eine zweite Existenzprüfung, die den Zugriff garantiert.
  3. Den Schreibmodus, um die erwartete Eingabe leer neu zu erstellen.
  4. Eine Bereinigung, um den fehlenden Dateinamen zu entfernen.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Ein Skript muss unabhängig vom Startverzeichnis data/menu.txt neben seinem eigenen Speicherort lesen. Welcher Ausdruck erstellt diesen Pfad im Skript?
  1. Path.cwd() / "data" / "menu.txt"
  2. Path(__file__).resolve().parent / "data" / "menu.txt"
  3. Path(__file__) / "data" / "menu.txt"
  4. Path("data") / "menu.txt"
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Eine UTF-8-CSV-Datei beginnt mit einer Byte-Reihenfolgemarkierung. Mit encoding="utf-8" lautet ihr erster Schlüssel aus der Kopfzeile "\ufeffcode". Welche Änderung beim Öffnen entfernt die Markierung und erhält den UTF-8-Text?
  1. Verwende encoding="utf-8-sig" für die Datei.
  2. Verwende newline="\n" statt newline="".
  3. Verwende delimiter=";" statt eines Kommas.
  4. Verwende skipinitialspace=True für alle Felder.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Eine Zeile ist {"title": "Map", "stock": "4", "cost": "3.50"}. Ein standardmäßiger DictWriter hat fieldnames=["title", "stock"]. Was geschieht, wenn er die ganze Zeile unverändert schreibt?
  1. Er schreibt zwei Felder und lässt cost weg.
  2. Er fügt cost automatisch zur Kopfzeile hinzu.
  3. Er löst wegen des zusätzlichen Schlüssels ValueError aus.
  4. Er schreibt cost als drittes unbenanntes Feld.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Eine Eingabeschleife fängt ValueError von int(text) ab. Dieser Behandler gibt missing_name aus, einen Namen, der nie definiert wurde. Was geschieht mit dem neuen NameError?
  1. Dasselbe except ValueError versucht die Anweisung automatisch erneut.
  2. Er wird zum ursprünglichen Umwandlungsfehler.
  3. Der Behandler unterdrückt ihn und endet regulär.
  4. Er wird weitergegeben, sofern kein äußerer Behandler ihn abfängt.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Nach einer Kopfzeile beginnt ein CSV-Datensatz mit "North in der physischen Zeile 2 und endet mit Hall",7 in Zeile 3. Welche Stelle meldet reader.line_num nach dem Lesen?
  1. 1
  2. 3
  3. 2
  4. 7
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Eine Hilfsfunktion gibt bei einer negativen Größe „bad size“ aus und gibt None zurück. Der aufrufende Code multipliziert das Ergebnis sofort mit 4. Warum würde das Auslösen von ValueError bei der Prüfung diesen Fehlerpfad verbessern?
  1. Es gibt einen Zahlenstandardwert für spätere Rechnungen zurück.
  2. Es garantiert, dass der aufrufende Code die Anfrage wiederholt.
  3. Es meldet die ungültige Größe, bevor spätere Rechnungen fehlschlagen.
  4. Es meldet einen Typumwandlungsfehler vor der Prüfung.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Nachdem ein Behandler einen KeyError als err abgefangen hat, führt er raise ValueError("missing unit column") from err aus. Was erhält der aufrufende Code und welche Ursache bleibt erhalten?
  1. Einen KeyError, verursacht durch den ValueError.
  2. Einen ValueError, verursacht durch den KeyError.
  3. Einen ValueError ohne eine frühere Ursache.
  4. Eine reguläre Rückgabe mit beiden Meldungszeichenketten.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Set 5: Dateiverarbeitung mit zuverlässigem Fehlerverhalten verbinden10 Übungsfragen

Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.

Frage 1 von 10

Ein Programm führt with open("source.txt", encoding="utf-8") as src, open("new.txt", "x", encoding="utf-8") as dst: aus. Die Quelldatei wird geöffnet, aber new.txt existiert bereits. Was geschieht mit src und dem Block?
  1. src wird geschlossen; FileExistsError verhindert den Block.
  2. src bleibt offen; der Block läuft ohne Zieldatei.
  3. src wird geschlossen; der Block hängt an die Zieldatei an.
  4. src bleibt offen; der Block ersetzt die Zieldatei.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 2 von 10

Ein Protokoll enthält "10:00 INFO ERROR resolved", "10:01 ERROR Disk slow" und "10:02 ERROR Disk full". Das zweite Feld ist die Stufe. Wie viele Datensätze werden nach dem Filtern nach der Fehlerstufe gespeichert?
  1. 1
  2. 0
  3. 3
  4. 2
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 3 von 10

Ein Prozess startet in /srv/course, führt tools/read.py aus und öffnet "../shared/items.txt". Welchen Pfad fordert er an?
  1. /srv/course/shared/items.txt
  2. /srv/shared/items.txt
  3. /srv/course/tools/shared/items.txt
  4. /shared/items.txt
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 4 von 10

Ein standardmäßiger CSV-Schreiber erhält ["Vale, East", None, 3]. Welcher Datensatz entsteht, wenn du seinen abschließenden Zeilenabschluss außer Acht lässt?
  1. Vale, East,None,3
  2. "Vale, East",,3
  3. "Vale, East",None,3
  4. Vale,East,,3
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 5 von 10

Ein Skript dividiert 30 durch die fest im Code stehende Zahl 5, obwohl die beabsichtigte Anzahl 6 ist. Es gibt ohne Ausnahme 6.0 aus. Um welche Art von Problem handelt es sich?
  1. Einen durch den Divisor verursachten Syntaxfehler.
  2. Einen TypeError bei der Division von Zahlen.
  3. Einen Logikfehler bei der gewählten Anzahl.
  4. Einen ZeroDivisionError bei der Summe.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 6 von 10

Was wird ausgegeben, bevor der Fehler weitergegeben wird?

try:
    n = int("2")
except ValueError:
    print("bad input")
else:
    print("ready")
    result = 9 / 0
finally:
    print("cleanup")
  1. „bad input“, dann „cleanup“
  2. Nur „ready“
  3. Nur „cleanup“
  4. „ready“, dann „cleanup“
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 7 von 10

Ein Parser muss jede Zeichenkette akzeptieren, die int() akzeptiert, einschließlich führender Leerzeichen und eines Vorzeichens. Warum sollte er int(text) in try versuchen, statt zuerst text.isdigit() zu verlangen?
  1. Die Operationen akzeptieren unterschiedliche Zeichenketten.
  2. isdigit() wandelt Zeichenketten mit Vorzeichen in ganze Zahlen um.
  3. int() akzeptiert jede Zeichenkette, die eine Ziffer enthält.
  4. Eine try-Anweisung entfernt Leerzeichen aus der Eingabe.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 8 von 10

Ein Werkzeug führt sys.exit("Required file unavailable") innerhalb von Code aus, der durch except Exception: abgedeckt ist. Was geschieht?
  1. Der Behandler erhält ValueError und versucht es erneut.
  2. Das Werkzeug gibt die Meldung als regulären Wert zurück.
  3. SystemExit umgeht den Behandler; der Beendigungsstatus ist 1.
  4. Der Behandler erhält SystemExit und setzt die Ausführung fort.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 9 von 10

Eine CSV-Zusammenfassung initialisiert total = 0 und skipped = 0. Ein innerer Behandler überspringt eine Zeile, wenn sie weniger als zwei Felder hat oder int(row[1]) fehlschlägt. Er addiert gültige umgewandelte Werte zur Summe. Welches endgültige Paar wird für die Zeilen ["lamp", "8"], ["desk"], ["chair", "bad"] und ["shelf", "5"] ausgegeben?
  1. total = 8, skipped = 1
  2. total = 13, skipped = 2
  3. total = 13, skipped = 1
  4. total = 8, skipped = 2
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Frage 10 von 10

Bei class ImportDataError(Exception): pass fängt aufrufender Code nur ValueError ab. Was geschieht, wenn seine Hilfsfunktion ImportDataError auslöst?
  1. Er wird weitergegeben, weil seine Klasse außerhalb des ValueError-Zweigs liegt.
  2. Er wird abgefangen, weil auch ValueError von Exception abstammt.
  3. Er wird abgefangen, wenn seine Meldung einen unzulässigen Wert beschreibt.
  4. Er wird zu ValueError, wenn die Hilfsfunktion ihn weitergibt.
Antwort zeigenAntwort ausblenden

Speichere diese Einheit, um diese Antwort zu sehen.

Hängst du bei deiner eigenen Aufgabe fest? Hausaufgabenhilfe

Schlüsselbegriffe

83 Schlüsselbegriffe, jeweils mit Definition

A

absoluter Pfad
Ein absoluter Pfad gibt einen Ort ausgehend von einer Dateisystemwurzel an, etwa / auf Unix-ähnlichen Systemen oder einer Laufwerkswurzel unter Windows.
Der Ort /Users/maya/data/notes.txt hängt nicht vom aktuellen Arbeitsverzeichnis ab.
Akkumulator
Ein Akkumulator ist eine Variable, die während einer Schleife aktualisiert wird, um aus den verarbeiteten Datensätzen ein Ergebnis wie eine Summe oder eine Anzahl aufzubauen.
Die Variable errors beginnt bei 0 und erhöht sich jedes Mal um 1, wenn die Schleife einen Datensatz der Fehlerstufe findet.
aktuelles Arbeitsverzeichnis
Das aktuelle Arbeitsverzeichnis ist das aktuelle Verzeichnis des Prozesses und dient Python beim Interpretieren relativer Pfade als Ausgangsort.
Das Ausführen von python tools/report.py vom Wurzelverzeichnis des Projekts aus wechselt nicht von selbst in das Verzeichnis tools.
Anfügemodus
Der Anfügemodus öffnet eine Datei so, dass neue Ausgaben am Ende hinzugefügt und vorhandene Inhalte behalten werden; eine fehlende Datei wird erstellt.
Die Verwendung von "a" für Durchlaufmeldungen erhält frühere Durchläufe, aber die Meldung benötigt weiterhin ein eigenes Zeilenumbruchzeichen.
AttributeError
Ein AttributeError signalisiert die Anforderung eines Attributs oder einer Methode, die ein Objekt nicht bereitstellt.
Der Aufruf von "hi".push("!") löst AttributeError aus, weil eine Python-Zeichenkette keine Methode namens push hat.
aufrufender Code
Der aufrufende Code ruft eine Funktion auf und erhält ihr zurückgegebenes Ergebnis oder eine Ausnahme, die die Funktion unbehandelt lässt.
Der aufrufende Code kann eine ungültige Auszahlung abfangen und nach einem kleineren Betrag fragen, ohne die Hilfsfunktion für die Berechnung zu ändern.
Ausnahme
Eine Ausnahme ist ein Objekt, das einen Fehler signalisiert und die normale Ausführung unterbricht, während Python nach einem passenden Behandler sucht.
Eine fehlgeschlagene Umwandlung mit int("many") löst eine Ausnahme aus, bevor die nächste Anweisung in diesem Block ausgeführt wird.
Ausnahmebehandler
Ein Ausnahmebehandler ist ein except-Block, der anhand eines passenden Ausnahmetyps ausgewählt wird, um kontrolliert auf eine fehlgeschlagene Operation zu reagieren.
Ein ValueError-Behandler kann erklären, dass eine Menge eine ganze Zahl sein muss, und eine umgebende Schleife erneut fragen lassen.
Ausnahmehierarchie
Eine Ausnahmehierarchie ist die Struktur aus über- und untergeordneten Fehlerklassen, die bestimmt, wie Behandler für allgemeinere Typen passen.
Ein Behandler für OSError passt auch auf FileNotFoundError, während ein ValueError-Behandler nicht auf KeyError passt.
Ausnahmeverkettung
Die Ausnahmeverkettung vermerkt mit raise ... from err einen früheren Fehler als direkte Ursache einer neuen Ausnahme.
Ein fehlender Preisschlüssel kann zu einem klareren Zeilenfehler werden, während der Traceback den ursprünglichen KeyError als Ursache erhält.

B

Beendigungsstatus
Ein Beendigungsstatus ist ein numerisches Ergebnis, das beim Programmende an das Betriebssystem gesendet wird und einem anderen Programm ermöglicht, einen Fehler zu erkennen.
sys.exit("Missing input") gibt die Meldung auf der Fehlerausgabe aus und endet mit dem Beendigungsstatus 1.
benutzerdefinierte Ausnahme
Eine benutzerdefinierte Ausnahme ist eine im Programm definierte Fehlerklasse, mit der aufrufender Code ein bestimmtes Problem getrennt von anderen Fehlern erkennen kann.
Ein InsufficientFundsError kann eine Aufforderung zu einem kleineren Betrag auslösen, während andere ungültige Werte eine andere Reaktion erhalten.
Binärmodus
Der Binärmodus liest und schreibt rohe Bytes statt dekodierter Zeichenketten und nimmt daher kein Argument für eine Zeichenkodierung entgegen.
Ein Modus wie "rb" bezeichnet die Eingabe von Bytes, während die Texteingabe einen Modus wie "r" verwendet.
Bindung einer Ausnahme
Eine Bindung einer Ausnahme gibt einem abgefangenen Fehlerobjekt mit as einen Namen, sodass sein Typ oder seine Meldung innerhalb dieses Behandlers untersucht werden kann.
In except ValueError as err: zeigt die Ausgabe von err die Meldung; die Bindung wird danach gelöscht.
Byte-Reihenfolgemarkierung
Eine Byte-Reihenfolgemarkierung ist eine anfängliche Markierung der Zeichenkodierung, die einige UTF-8-Exporte enthalten und die im ersten Feld erscheinen kann, wenn sie erhalten bleibt.
Das Lesen mit encoding="utf-8-sig" entfernt die anfängliche Markierung, sodass der erste Spaltenname dem beabsichtigten Namen entspricht.

C

CSV
CSV ist ein Textformat für Tabellendatensätze aus getrennten Feldern, dessen Regeln für Anführungszeichen Trennzeichen und Zeilenumbrüche innerhalb von Werten erlauben.
Der Datensatz "Lopez, Maria",10,8 hat drei Felder, weil sein erstes Komma innerhalb eines Namens in Anführungszeichen steht.
CSV-Schreiber
Ein CSV-Schreiber serialisiert Sequenzen von Feldwerten zu Datensätzen, wandelt Werte in Text um und wendet die gewählten Regeln für Anführungszeichen an.
Ein CSV-Schreiber setzt einen Produktnamen mit Komma automatisch in Anführungszeichen, wenn das Programm ihn als ein Feld übergibt.

D

Dateiendung
Eine Dateiendung ist die letzte Endung eines Dateinamens einschließlich des vorangestellten Punkts und ist über die Eigenschaft suffix eines Pfads verfügbar.
Die Dateiendung von Path("data/sales.csv") ist ".csv", was ein Programm bei der Auswahl von Tabellendateien verwenden kann.
Dateimodus
Ein Dateimodus ist ein Argument für open(), das den erlaubten Zugriff und den Umgang mit vorhandenem Inhalt unter dem Pfad beim Öffnen festlegt.
Ein Aktivitätenprotokoll verwendet "a", um frühere Meldungen zu behalten, während ein neuer Bericht sie mit "w" ersetzen kann.
Dateiname ohne letzte Endung
Der Dateiname ohne letzte Endung ist der letzte Bestandteil eines Pfads ohne sein letztes Suffix und hilft dabei, verwandte Ausgabenamen aus einem Dateinamen abzuleiten.
Für Path("logs/run.txt") ist der Dateiname ohne letzte Endung "run", während der vollständige letzte Name "run.txt" lautet.
Dateiobjekt
Ein Dateiobjekt ist das von open() zurückgegebene Objekt, das einem Programm Methoden zum Lesen oder Schreiben einer geöffneten Datei bereitstellt.
Innerhalb von with open("notes.txt", encoding="utf-8") as f: verweist der Name f auf das Dateiobjekt.
Dateiposition
Eine Dateiposition markiert, wo der nächste Lesevorgang beginnt, und rückt vor, während das Programm Text aus der Datei liest.
Nachdem f.read() den verbleibenden Inhalt gelesen hat, gibt ein zweites Lesen eine leere Zeichenkette zurück.
Datensatz
Ein Datensatz ist eine vollständige Zeile aus CSV-Feldern; er belegt meist eine physische Zeile, kann sich aber durch ein Feld in Anführungszeichen über mehrere Zeilen erstrecken.
Eine Adresse mit Zeilenumbruch in Anführungszeichen bleibt beim Lesen durch das CSV-Modul ein Datensatz.
Datensatzabschluss
Ein Datensatzabschluss ist die Zeichenfolge, die ein CSV-Schreiber nach einer Zeile hinzufügt; der Standardschreiber verwendet "\r\n".
Das Öffnen mit newline="" lässt den CSV-Schreiber seine eigenen Abschlüsse ohne eine zweite Umwandlung bereitstellen.
delegierte Ausnahmebehandlung
Die delegierte Ausnahmebehandlung überlässt eine Ausnahme dem aufrufenden Code, der den nötigen Kontext hat, um für die größere Aufgabe eine hilfreiche Reaktion zu wählen.
Eine Datenhilfsfunktion meldet einen Fehler, während der Kommandozeilenteil entscheidet, ob erneut versucht, eine Datei übersprungen oder gestoppt wird.
DictReader
Ein DictReader liest CSV-Datensätze als Wörterbücher, deren Schlüssel aus der Kopfzeile stammen, während die Feldwerte standardmäßig Zeichenketten bleiben.
Nach der Kopfzeile name,score kann mit row["score"] auf eine Zeile zugegriffen werden, auch wenn die Spalten neu angeordnet werden.
DictWriter
Ein DictWriter schreibt Wörterbücher als CSV-Zeilen und verwendet eine übergebene Sequenz von Feldnamen, um die Spalten und ihre Reihenfolge zu wählen.
Ein CSV-Schreiber mit fieldnames=["product", "stock"] exportiert diese Spalten, wenn ihm passende Wörterbücher übergeben werden.

E

Einschließen in Anführungszeichen
Das Einschließen in Anführungszeichen umgibt ein Feld mit Anführungszeichen, sodass ein Trennzeichen oder Zeilenumbruch innerhalb seines Werts Teil dieses Feldes bleibt.
Der Leser behält das Komma innerhalb von "River, West", während eine einfache Aufteilung an Kommas diesen Namen zerlegen würde.
else-Klausel
Eine else-Klausel einer try-Anweisung wird ausgeführt, wenn der geschützte Block regulär, ohne Ausnahme oder vorzeitiges Verlassen, endet.
Eine erfolgreiche Umwandlung kann zu einer Ausgabe in else führen, während ein bei dieser Ausgabe ausgelöster Fehler nicht von den vorherigen Behandlern abgefangen wird.
Entfernen von Leerraumzeichen am Rand
Das Entfernen von Leerraumzeichen am Rand entfernt führende oder abschließende Leerraumzeichen aus Text, darunter Leerzeichen, Tabulatorzeichen und Zeilenabschlüsse.
Nach line.strip() wird eine Zeile, die nur Leerzeichen und ein Zeilenumbruchzeichen enthält, zu einer leeren Zeichenkette.
erneutes Auslösen einer Ausnahme
Das erneute Auslösen einer Ausnahme gibt die aktive abgefangene Ausnahme mit einem bloßen raise weiter und ermöglicht eine lokale Reaktion, ohne den Fehler als behoben zu behandeln.
Ein Leser gibt den fehlenden Pfad aus und löst die Ausnahme erneut aus, damit der aufrufende Code entscheiden kann, ob eine andere Datei angefordert wird.
Erstellen von Verzeichnissen
Das Erstellen von Verzeichnissen legt Verzeichnisse im Dateisystem an; mkdir(parents=True) kann auch fehlende übergeordnete Verzeichnisse erstellen.
Erstelle output/daily vor dem Schreiben seines Berichts, da das Öffnen einer neuen Ausgabedatei keine Verzeichnisse erstellt.
exklusives Erstellen
Exklusives Erstellen legt nur dann eine neue Datei an, wenn der Pfad unbelegt ist, und löst FileExistsError aus, falls dort bereits eine Datei existiert.
Der Modus "x" verhindert, dass ein neu erzeugter Bericht einen Bericht unter demselben Pfad stillschweigend ersetzt.

F

fehlendes Feld
Ein fehlendes Feld ist ein Wert, der in einem kurzen CSV-Datensatz fehlt; ein standardmäßiger DictReader füllt seinen bekannten Schlüssel aus der Kopfzeile mit None.
Unter name,score hat die Zeile Ana einen fehlenden Punktzahlwert; Ana, enthält dagegen eine leere Zeichenkette für die Punktzahl.
Fehlerbehandlung auf Datensatzebene
Die Fehlerbehandlung auf Datensatzebene behandelt einen erwarteten Fehler eines Datensatzes innerhalb der Verarbeitungsschleife, sodass spätere Datensätze berücksichtigt werden können, wenn dies erlaubt ist.
Eine schnelle Zusammenfassung meldet eine fehlerhafte Menge und erhöht den Zähler für übersprungene Zeilen, bevor der nächste CSV-Datensatz gelesen wird.
Fehlermeldung
Eine Fehlermeldung beschreibt eine fehlgeschlagene Operation oder einen zurückgewiesenen Wert, sodass die lesende Person versteht, was geschehen ist und was korrigiert werden muss.
Die Meldung „pages must be positive, got -2“ ist hilfreicher als das einzelne Wort „error“.
Feld
Ein Feld ist ein bedeutungstragender Teil eines Datensatzes, der durch ein bekanntes Format getrennt oder bezeichnet wird, etwa eine Protokollstufe oder eine CSV-Mengenangabe.
In einem Protokoll mit Datum, Uhrzeit, Stufe und Meldung verhindert die Prüfung der Stufe einen Treffer für ein Wort innerhalb der Meldung.
Feldtrennzeichen
Ein Feldtrennzeichen ist das Zeichen, das Felder in einem Tabellenformat trennt, etwa ein für einen CSV-Leser gewähltes Komma, Semikolon oder Tabulatorzeichen.
Ein Export mit Semikolons benötigt delimiter=";", damit ein Leser name;score in zwei Felder trennt.
fieldnames
Die Sequenz fieldnames enthält die von einem DictReader gelesenen Namen der Kopfzeile oder die erwarteten Ausgabeschlüssel und ihre Reihenfolge für einen DictWriter.
Der Aufruf von writeheader() bei einem DictWriter gibt die Namen in der festgelegten Reihenfolge von fieldnames aus.
FileExistsError
Ein FileExistsError signalisiert eine Operation, die einen unbelegten Pfad benötigt, wenn an diesem Ort bereits etwas existiert.
Das Öffnen eines vorhandenen Berichts mit dem Modus "x" löst FileExistsError aus, statt seinen Inhalt zu ersetzen.
FileNotFoundError
Ein FileNotFoundError signalisiert, dass eine angeforderte Datei oder ein angefordertes Verzeichnis unter dem von einer Dateisystemoperation verwendeten Pfad nicht gefunden werden kann.
Ein falsches Startverzeichnis kann dazu führen, dass ein relativer Eingabepfad FileNotFoundError auslöst, obwohl die Datei anderswo existiert.
finally-Klausel
Eine finally-Klausel führt das Aufräumen aus, wenn der Ablauf eine try-Anweisung verlässt, auch bevor eine ausstehende Rückgabe abgeschlossen oder eine unbehandelte Ausnahme weitergegeben wird.
Eine Abschlussmeldung in finally wird auch ausgegeben, wenn eine Umwandlung fehlschlägt und kein zugehöriger Behandler zu ihrem Typ passt.

G

geschlossene Datei
Eine geschlossene Datei ist ein Dateiobjekt, dessen zugrunde liegender Dateizugriff beendet wurde, sodass darüber kein weiteres Lesen oder Schreiben möglich ist.
Nachdem ein with-Block endet, der eine Datei als f geöffnet hat, ist f.closed gleich True und f.read() löst einen ValueError zum Zugriff auf eine geschlossene Datei aus.
Glob-Muster
Ein Glob-Muster wählt Pfade anhand eines Namensmusters aus, wobei ein Platzhalter wie * für unterschiedlichen Text innerhalb des ausgewählten Verzeichnisses steht.
Path("logs").glob("*.txt") findet passende Pfade zu Textdateien; ihre Sortierung ergibt eine vorhersehbare Verarbeitungsreihenfolge.

I

IndexError
Ein IndexError signalisiert einen Zugriff auf eine nicht vorhandene Position in einer Sequenz, etwa einen Indexzugriff über das Ende einer Liste hinaus.
Eine kurze CSV-Zeile mit einem Feld löst IndexError aus, wenn positionsbasierter Code versucht, auf ihr zweites Feld zuzugreifen.
IsADirectoryError
Ein IsADirectoryError signalisiert eine Operation, die eine Datei erwartet, aber am angeforderten Ort auf ein Verzeichnis trifft.
Auf Systemen, die diesen Fall unterscheiden, löst das Öffnen eines Verzeichnisses als gewöhnliche Eingabedatei IsADirectoryError aus.

K

KeyboardInterrupt
Ein KeyboardInterrupt signalisiert eine Benutzerunterbrechung, häufig Strg+C, und gehört direkt zu BaseException statt zu Exception.
Ein bloßes except: kann Strg+C abfangen, während except Exception: die Unterbrechung weitergeben lässt.
KeyError
Ein KeyError signalisiert das Nachschlagen eines fehlenden Wörterbuchschlüssels, etwa wenn ein Name in der CSV-Kopfzeile nicht mit dem angeforderten Schlüssel übereinstimmt.
Das Nachschlagen von row["name"] schlägt fehl, wenn die Kopfzeile der Tabelle stattdessen den Schlüssel "Name" erzeugt hat.
Kontextmanager
Ein Kontextmanager ist ein Objekt, das das Verhalten beim Betreten und Verlassen eines with-Blocks organisiert, etwa das Bereitstellen des Zugriffs und das Aufräumen.
Ein Dateiobjekt dient als Kontextmanager, sodass sich ein Programm beim Verlassen des Blocks auf das automatische Schließen verlassen kann.
kontrolliertes Scheitern
Kontrolliertes Scheitern ist eine beherrschte Reaktion auf ein Problem, die hilfreiche Informationen gibt und je nach Aufgabe fortfährt oder stoppt.
Eine fehlende Berichtsdatei führt zu einer klaren Aufforderung, den Pfad zu korrigieren, statt zu einem für den Benutzer verwirrenden Absturz.
Kopfzeile
Eine Kopfzeile ist eine Zeile mit Spaltennamen, die die Felder einer Tabelle bezeichnet und in einer CSV-Datei häufig vor den Datensätzen steht.
Die Zeile product,stock,price benennt Spalten und sollte nicht als Daten an eine Umwandlung in ganze Zahlen übergeben werden.

L

Leeren der Datei
Das Leeren der Datei entfernt den vorhandenen Inhalt einer Datei beim Öffnen im Schreibmodus, bevor das Programm neuen Text bereitstellt.
Das Öffnen einer Eingabedatei mit "w" zerstört die alten Datensätze, selbst wenn das Programm nie einen Schreibaufruf erreicht.
Logikfehler
Ein Logikfehler führt durch falsche Überlegungen oder Operationen dazu, dass ein Programm ein falsches Ergebnis erzeugt, ohne dass eine Ausnahme auftreten muss.
Die Division durch eine falsche Anzahl ungleich null kann ein plausibles arithmetisches Mittel erzeugen, während das Programm vollständig durchläuft.

N

NameError
Ein NameError signalisiert die Verwendung eines Namens ohne verfügbare Bindung, oft weil er falsch geschrieben oder ihm nie etwas zugewiesen wurde.
Ein Behandler, der eine nicht definierte Variable ausgibt, löst NameError aus, während er versucht, das ursprüngliche Problem zu melden.

P

Path-Objekt
Ein Path-Objekt stellt einen Pfad in Python dar und bietet Operationen, um Bestandteile zusammenzufügen, Namen zu untersuchen und auf das Dateisystem zuzugreifen.
Der Ausdruck Path("data") / "scores.txt" erstellt einen Ort, den open() direkt akzeptieren kann.
PermissionError
Ein PermissionError signalisiert, dass das Betriebssystem den von einer Dateisystemoperation angeforderten Zugriff verweigert.
Eine Eingabedatei kann existieren und dennoch PermissionError auslösen, wenn das Programm keine Berechtigung zum Lesen hat.
Pfad
Ein Pfad beschreibt den Ort einer Datei oder eines Verzeichnisses durch Namen und Trennzeichen, ausgehend von einer Wurzel oder einem anderen bekannten Verzeichnis.
Der Pfad data/notes.txt bezeichnet eine Textdatei im Datenverzeichnis unter dem aktuellen Arbeitsverzeichnis.
physische Zeilennummer
Eine physische Zeilennummer zählt die tatsächlichen Dateizeilen. Sie kann von der Anzahl der CSV-Datensätze abweichen, wenn ein Feld in Anführungszeichen einen Zeilenumbruch enthält.
Das Attribut line_num des Lesers bezeichnet die zuletzt gelesene Zeile eines Datensatzes, der sich über zwei Zeilen erstreckt.
Puffer
Ein Puffer ist ein vorübergehender Speicherbereich, der Daten während der Ein- oder Ausgabe hält, etwa geschriebenen Text, der noch auf die Übertragung in eine Datei wartet.
Das Schließen einer Ausgabedatei leert ihren Textpuffer, sodass die ausstehenden Schreibvorgänge an die Datei übergeben werden.

R

raise-Anweisung
Eine raise-Anweisung signalisiert ausdrücklich eine Ausnahme, unterbricht den normalen Ablauf und beginnt die Suche nach einem passenden Behandler.
Eine Funktion weist einen nicht positiven Betrag vor der Berechnung mit raise ValueError("amount must be positive") zurück.
relativer Pfad
Ein relativer Pfad gibt einen Ort ausgehend vom aktuellen Arbeitsverzeichnis des Prozesses an, sodass seine Bedeutung von diesem Ausgangsverzeichnis abhängt.
Beim Start in project/scripts verweist ../data/notes.txt in das benachbarte Datenverzeichnis des Projekts.
rohe Zeichenkette
Eine rohe Zeichenkette verwendet ein Präfix r, sodass umgekehrte Schrägstriche als wörtliche Zeichen erhalten bleiben, statt als gewöhnliche Escape-Sequenzen interpretiert zu werden.
Das Literal r"C:\new\table.txt" erhält die Trennzeichen, die sonst Escape-Sequenzen für Zeilenumbruch und Tabulator beginnen würden.

S

spezifischer Ausnahmebehandler
Ein spezifischer Ausnahmebehandler fängt eine eng gefasste Ausnahmeklasse ab, sodass erwartete Probleme eigene Meldungen erhalten können, ohne jeden Programmfehler zu verbergen.
Setze FileNotFoundError vor OSError, wenn eine fehlende Datei eine andere Reaktion als andere Dateiprobleme benötigt.
SystemExit
Ein SystemExit signalisiert eine beabsichtigte Prozessbeendigung und wird von sys.exit() außerhalb des gewöhnlichen Exception-Zweigs ausgelöst.
Der Aufruf von sys.exit("Missing data") löst SystemExit mit einer Meldung und einem Fehlerstatus aus, den ein gewöhnlicher Exception-Behandler nicht abfängt.

T

Textdatei
Eine Textdatei speichert Zeichen als kodierte Bytes, die meist in Zeilen angeordnet sind, und behält ihre Daten nach dem Ende des schreibenden Programms.
Ein Programm liest zu Beginn des nächsten Durchlaufs eine gespeicherte Liste von Punktzahlen aus einer Textdatei.
Traceback
Ein Traceback berichtet über die Aufrufkette, die zu einer unbehandelten Ausnahme geführt hat, und endet mit dem Ausnahmetyp und einer erläuternden Meldung.
Der unterste Aufrufeintrag kann die Division durch die Länge einer leeren Liste als fehlgeschlagene Operation ausweisen.
try-Block
Ein try-Block enthält Operationen, deren Ausnahmen von den zugehörigen Klauseln behandelt werden können; bei einem Fehler wird der restliche Code übersprungen.
Eine Eingabeumwandlung gehört in einen kleinen try-Block, damit ein fehlerhafter Wert eine Aufforderung zu einer erneuten Eingabe auslösen kann.
TypeError
Ein TypeError signalisiert eine Operation mit einer ungeeigneten Objektart oder einer unverträglichen Kombination von Objekttypen.
Die Addition von "5" und 3 löst TypeError aus, weil die Zeichenkettenaddition keine ganze Zahl als zweiten Operanden akzeptiert.

U

UnicodeDecodeError
Ein UnicodeDecodeError signalisiert, dass gespeicherte Bytes nach den gewählten Regeln zur Interpretation von Text nicht dekodiert werden können.
Ein Textleser kann UnicodeDecodeError auslösen, wenn die tatsächliche Zeichenkodierung der Datei nicht zu encoding="utf-8" passt.
UTF-8
UTF-8 ist eine Zeichenkodierung, die jedes Unicode-Zeichen darstellen kann und eine variable Anzahl von Bytes pro Zeichen verwendet.
Verwende encoding="utf-8" beim Öffnen einer als UTF-8 gespeicherten Textdatei, damit ihre Buchstaben mit Akzenten korrekt dekodiert werden.

Ü

übergeordnete Ausnahmeklasse
Eine übergeordnete Ausnahmeklasse ist die Klasse, von der eine andere Fehlerklasse abgeleitet wird, sodass ihre Behandler auch auf Instanzen dieses Untertyps passen.
Die Ableitung von LimitError aus ValueError ermöglicht es einem vorhandenen ValueError-Behandler, auch diesen Fehler abzufangen.
übergeordnetes Verzeichnis
Ein übergeordnetes Verzeichnis ist das Verzeichnis, das eine Datei oder ein Verzeichnis enthält; die Eigenschaft parent eines Pfads wählt diesen umschließenden Ort aus.
Für Path("reports/2026/sales.csv") ist das übergeordnete Verzeichnis der Pfad reports/2026.

V

Validierung
Die Validierung prüft, ob eine Eingabe die Anforderungen einer Operation erfüllt, bevor das Programm sie zur Erzeugung eines Ergebnisses verwendet.
Eine Auszahlungsfunktion prüft vor der Subtraktion, ob der Betrag positiv ist und den Kontostand nicht übersteigt.
ValueError
Ein ValueError signalisiert, dass eine Operation eine erlaubte Objektart erhalten hat, deren Wert sie für diese Aufgabe aber nicht interpretieren oder akzeptieren kann.
Die Zeichenkette "3.5" ist ein erlaubter Eingabetyp für int(), aber keine Zeichenkette für eine ganze Zahl und löst ValueError aus.

W

Weitergabe einer Ausnahme
Die Weitergabe einer Ausnahme führt eine unbehandelte Ausnahme durch die aufrufenden Funktionen nach außen, bis ein passender Behandler gefunden wird oder die Ausführung endet.
Eine Hilfsfunktion zum Lesen einer Datei kann FileNotFoundError an den aufrufenden Code gelangen lassen, der weiß, ob ein anderer Pfad angefordert werden soll.
with-Anweisung
Eine with-Anweisung betritt einen verwalteten Block und sorgt für das Aufräumen, wenn der Ablauf ihn verlässt; bei einer geöffneten Datei wird diese dabei geschlossen.
Eine in einem with-Block geöffnete Datei wird auch geschlossen, wenn die Umwandlung einer Zeile innerhalb des Blocks einen Fehler auslöst.
writerow
Die Methode writerow schreibt eine Sequenz von Feldwerten als CSV-Datensatz, einschließlich benötigter Trennzeichen, Anführungszeichen und eines Datensatzabschlusses.
Verwende writer.writerow(["Ana", 8.5]) für einen Datensatz mit zwei Feldern, keine bereits zusammengefügte Zeichenkette.
writerows
Die Methode writerows schreibt eine Sequenz von Zeilen und behandelt jede übergebene Zeile als Sequenz von Feldern für einen CSV-Datensatz.
Eine Liste von Listen mit Namen und Punktzahlen kann an writerows() übergeben werden, um mehrere Datensätze mit einem Aufruf zu speichern.

Z

Zeichenkodierung
Eine Zeichenkodierung ist ein Regelsatz zur Darstellung von Zeichen als Bytes, der beim Schreiben und beim Interpretieren gespeicherten Textes verwendet wird.
Der Text „café“ kann verstümmelt werden, wenn ein Leser eine andere Zeichenkodierung als beim Speichern verwendet.
Zeilenfilter
Ein Zeilenfilter wählt beim Lesen einer Datei Datensätze anhand einer Bedingung aus, sodass das Programm nur die für eine Aufgabe relevanten Zeilen behalten kann.
Ein Protokollfilter prüft das Stufenfeld und schreibt nur Datensätze, deren Stufe "ERROR" entspricht.
Zeilenumbruchzeichen
Ein Zeilenumbruchzeichen, in einer Python-Zeichenkette als "\n" geschrieben, markiert einen Zeilenumbruch; die letzte Zeile einer Datei kann ohne Zeilenabschluss sein.
Die Ausgabe einer Zeile, die bereits auf "\n" endet, fügt ein weiteres Zeilenumbruchzeichen hinzu, sofern der Ausgabeabschluss nicht geändert wird.
ZeroDivisionError
Ein ZeroDivisionError signalisiert eine Division oder eine verwandte Rechenoperation mit einem Divisor null, die ein numerisches Ergebnis verhindert.
Eine Mittelwertberechnung löst ZeroDivisionError aus, wenn die Liste leer ist und ihre Länge als Divisor verwendet wird.
zusätzliches Feld
Ein zusätzliches Feld ist ein Datensatzwert über die Feldanzahl der Kopfzeile hinaus; ein standardmäßiger DictReader sammelt solche Werte unter dem Schlüssel None.
Bei zwei Namen in der Kopfzeile behält eine Zeile mit drei Werten ihre benannten Werte und speichert den zusätzlichen Wert in einer Liste.

Über diese Einheit

Von StudeliFehler melden

Erstelle deine eigenen Lernmaterialien

Mach aus deinen Notizen, Folien und Dokumenten Lernleitfäden, Übungsfragen, Karteikarten und 6 weitere Tools.

Jetzt starten