- Lernen
- Informatik & Informationswissenschaften
- Programmierung
- Python-Programmierung – Schleifen, Funktionen, Listen und Dateien
- Dateien und Ausnahmen in Python
Dateien und Ausnahmen in Python
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
- Ö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 lesenVerbinde 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ßenVerwende
with open(...) as f:, damit Dateien zum richtigen Zeitpunkt geschlossen werden, auch wenn etwas schiefgeht. - Text in Dateien schreiben und an Dateien anhängenWähle den richtigen Modus, um eine Datei zu erstellen, zu überschreiben oder zu erweitern, und schreibe Text mit
write()undprint(), sodass die Zeilen genau wie beabsichtigt entstehen. - Zeilen in einer Datei suchen, zählen und filternVerarbeite 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.
- Eine Textdatei öffnen und ihren Inhalt lesen
- 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 verwendenSchreibe 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 verwaltenVerwende
Path-Objekte aus dem Modulpathlib, 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.
- Relative und absolute Pfade richtig verwenden
- 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 lesenVerstehe, wie eine CSV-Datei eine Tabelle speichert, lies sie mit
csv.readerZeile für Zeile, überspringe die Kopfzeile und wandle die benötigten Werte um. - CSV-Dateien mit csv.writer schreibenErstelle 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 zugreifenLies 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.
- CSV-Daten mit csv.reader lesen
- 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 lesenErkenne, 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 abfangenSchreibe
try- undexcept-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 verfolgenErgänze eine
try-Anweisung umelseundfinally, sage die Reihenfolge ihrer Blöcke voraus und entscheide, in welcher Funktion eine Ausnahme behandelt werden soll. - Datei- und Datenprogramme kontrolliert auf Fehler reagieren lassenVerbinde 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.
- Häufige Ausnahmen erkennen und einen Traceback lesen
- 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ückzuweisenVerwende 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 definierenGib 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.
- Ausnahmen auslösen, um ungültige Eingaben zurückzuweisen
Dateien und Ausnahmen in Python einfach erklärt
1Textdateien 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.
| Operation | Ergebnis | Nützlich, wenn |
|---|---|---|
f.read() | Der gesamte verbleibende Text als eine Zeichenkette | Du eine kleine Datei als Ganzes brauchst |
f.readline() | Die nächste Zeile als Zeichenkette | Du jetzt eine Zeile brauchst |
f.readlines() | Alle verbleibenden Zeilen als Liste | Du die Zeilen erneut verwenden möchtest |
for line in f: | Eine Zeile pro Durchlauf | Du 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()oderfloat()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
withschließ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
tryundexcept.
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
| Modus | Vorhandene Datei | Fehlende Datei |
|---|---|---|
"r" | Öffnet zum Lesen | Löst FileNotFoundError aus |
"w" | Leert und öffnet dann zum Schreiben | Erstellt sie |
"a" | Fügt Ausgaben am Ende hinzu | Erstellt sie |
"x" | Löst FileExistsError aus | Erstellt 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üfung | Was sie fragt |
|---|---|
line.startswith("From:") | Beginnt die Zeile mit diesem Text? |
"ERROR" in line | Kommt 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.
2Dateien 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
| Art | Beispiel | Ausgangspunkt |
|---|---|---|
| Absolut, macOS oder Linux | /Users/maya/data/notes.txt | Die Wurzel / |
| Absolut, Windows | C:/Users/Maya/data/notes.txt | Das Wurzelverzeichnis von Laufwerk C |
| Relativ | data/notes.txt | Aktuelles 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
Pathfügt Teile mit/zusammen und funktioniert direkt mitopen().name,stem,suffixundparentgeben 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, undmkdir(), um fehlende Verzeichnisse zu erstellen.
3CSV-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.readerstatt 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 anwriterows(). - Der CSV-Schreiber wandelt Werte um und behandelt Anführungszeichen;
Nonewird 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
DictReaderliest 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
Noneabgelegt. DictWriterbenötigtfieldnames, um die Spaltenreihenfolge festzulegen.- Fehlende Ausgabeschlüssel werden zu leeren Feldern; unerwartete Schlüssel lösen standardmäßig
ValueErroraus.
4Fehler 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
| Typ | Typische Ursache |
|---|---|
ValueError | int("3.5"): eine Zeichenkette mit einem unzulässigen Wert |
TypeError | len(5): eine Operation mit der falschen Objektart |
ZeroDivisionError | Division durch null |
IndexError | Lesen einer Listenposition, die nicht existiert |
KeyError | Nachschlagen eines fehlenden Wörterbuchschlüssels |
NameError | Verwendung eines nicht definierten Namens |
AttributeError | Zugriff 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:
OSErrorist der übergeordnete Typ häufiger Dateisystemfehler, darunterFileNotFoundErrorundPermissionError.LookupErrorist der übergeordnete Typ vonIndexErrorundKeyError.ArithmeticErrorist der übergeordnete Typ vonZeroDivisionError.UnicodeDecodeErrorgehört zuValueError.
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.
ValueErrorbetrifft einen unzulässigen Wert;TypeErrorbetrifft 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 errermöglicht innerhalb des Behandlers den Zugriff auf die Meldung.- Halte das
tryauf 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
elsewird nur nach regulärer Beendigung destry-Blocks ausgeführt.finallywird vor dem Verlassen ausgeführt, auch bei einer Rückgabe oder einer unbehandelten Ausnahme.- Eine Ausnahme in
elseliegt außerhalb der vorherigen Behandler dieser Anweisung. - Vermeide das Verlassen von
finallyauf 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.
5Eigene 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
| Problem | Passender Typ |
|---|---|
| Richtige Art der Eingabe, unzulässiger Wert | ValueError |
| Falsche Objektart für die Operation | TypeError |
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
ValueErrorfür einen unzulässigen Wert undTypeErrorfü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
raisein einem Behandler gibt die aktuelle Ausnahme weiter. raise NewError(...) from errvermerkt 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
1Eine Textdatei in einen gefilterten Bericht umwandeln
13 Schritte
- 1Einfü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
withbeide Dateien schließen, wenn die Verarbeitung endet. - 2ErklärungEine Datei liefert Zeichenketten
Angenommen,
events.txtenthä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. - 3HerausforderungWä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 vonread()oderreadlines()würde den verbleibenden Inhalt in den Speicher laden. - 4BeispielLies 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
firstdanach stattfinden, ein weiteresf.readline()aber nicht. - 5HerausforderungSage das Aufräumen nach einem Fehler voraus
Angenommen, innerhalb dieses Dateiblocks löst
int("oops")ValueErroraus. Der umgebende Code hat keinen Behandler. Bleibt die Datei geöffnet und verbirgtwithden 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. - 6Erklä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 behandleFileExistsError. Zum Erstellen der Datei müssen die enthaltenden Verzeichnisse weiterhin existieren. - 7BeispielSchreibe 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 beiwritelines()die übergebenen Zeichenketten alle benötigten Zeilenabschlüsse enthalten müssen. - 8HerausforderungSage 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 ruftf.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 nochwrite()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. - 9BeispielBereinige 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
lineseparat behältst, kann die Ausgabe ihre Abstände erhalten. Nur die bereinigte Kopie wird verwendet, um die Stufe zu bestimmen. - 10HerausforderungPrü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. - 11BeispielSetze 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.
- 12HerausforderungUntersuche 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.
- 13ZusammenfassungVerfolge 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.
2Projektdaten von jedem Startverzeichnis aus finden
9 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungFinde das Startverzeichnis
- 2BeispielVerfolge einen Start
- 3HerausforderungÄndere das Startverzeichnis
- 4TippPrüfe, bevor du den Pfad änderst
- 5BeispielErstelle den Pfad ausgehend vom Skript
- 6ErklärungBereite ein Ziel vor
- 7HerausforderungUntersuche einen Namen und finde Treffer
- 8HerausforderungPrüfe einen Lösungsvorschlag
- 9ZusammenfassungUnterscheide Ort und Verfügbarkeit
3Eine Tabelle lesen und einen Bericht mit benannten Spalten schreiben
13 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungErhalte die Tabellenstruktur
- 2BeispielLies einen Datensatz mit Anführungszeichen
- 3BeispielÖffne und wandle um
- 4HerausforderungErkenne eine kurze Zeile
- 5BeispielSchreibe Werte als Felder
- 6HerausforderungHalte ein Feld zusammen
- 7ErklärungVerwende die Kopfzeile als Schlüssel
- 8BeispielFiltere nach Bestand
- 9HerausforderungUnterscheide fehlend und leer
- 10BeispielExportiere ausgewählte Spalten
- 11HerausforderungHänge später weitere Daten an
- 12TippWähle passende Trennzeichen und Zeichenkodierungen
- 13ZusammenfassungPrüfe Struktur und Bedeutung
4Einen Fehler von einer fehlerhaften Zeile bis zu einer hilfreichen Reaktion verfolgen
15 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungEntscheide, wo eine Fehlerbehandlung möglich ist
- 2BeispielBeginne mit dem Ausnahmetyp
- 3HerausforderungErkenne einen anderen Fehler
- 4BeispielFange nur den erwarteten Umwandlungsfehler ab
- 5HerausforderungOrdne verwandte Behandler
- 6ErklärungTrenne die Aufgaben bei Erfolg und beim Aufräumen
- 7HerausforderungVerfolge einen nicht abgefangenen Fehler
- 8VerbindungLass den aufrufenden Code entscheiden
- 9BeispielBehandle Fehler innerhalb der Datensatzschleife
- 10BeispielVerfolge drei Datensätze
- 11HerausforderungÄndere die Schleifengrenze
- 12TippBenenne die Stelle richtig
- 13HerausforderungEntscheide dich für ein vollständiges Ergebnis
- 14BeispielBeende das Programm mit einem Fehlerstatus
- 15ZusammenfassungPlatziere jede Reaktion auf der richtigen Ebene
5Das Fehlerverhalten einer Funktion gestalten
10 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungGib Fehlern einen klaren Pfad
- 2BeispielWeise ungültige Anfragen zurück
- 3HerausforderungVerfolge eine fehlgeschlagene Zuweisung
- 4ErklärungWähle den zum Problem passenden Typ
- 5BeispielBenenne einen gesonderten Platzmangel
- 6HerausforderungHalte die spezifische Reaktion erreichbar
- 7BeispielReagiere und gib den Fehler weiter
- 8BeispielWandle einen Fehler auf niedrigerer Ebene um
- 9HerausforderungWähle die richtige Beziehung
- 10ZusammenfassungGestalte den Fehler für den aufrufenden Code aussagekräftig
Dateien und Ausnahmen in Python: Übungsaufgaben
Set 1: Dateien lesen und kleine Programme nachvollziehen10 Übungsfragen
Frage 1 von 10
"oak\npine". Was gibt f.readline() unmittelbar nach dem Öffnen zum Lesen zurück?Antwort zeigenAntwort ausblenden
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)
Antwort zeigenAntwort ausblenden
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
Antwort zeigenAntwort ausblenden
"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
/work/lab. Es führt python tools/count.py aus, das "inputs/list.txt" öffnet. Welchen absoluten Ort bezeichnet dieser relative Pfad?Antwort zeigenAntwort ausblenden
/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
p = Path("exports/week/report.csv") der Wert von p.stem?Antwort zeigenAntwort ausblenden
"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
csv.reader aus dem Datensatz "River, West",6,8 gelesen?Antwort zeigenAntwort ausblenden
Frage 7 von 10
writer.writerow("Leo") mit dem standardmäßigen Komma als Feldtrennzeichen?Antwort zeigenAntwort ausblenden
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
"many". Welche Ausnahme löst int(row["quantity"]) aus?Antwort zeigenAntwort ausblenden
"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")
Antwort zeigenAntwort ausblenden
Frage 10 von 10
-2?Antwort zeigenAntwort ausblenden
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
"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?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
"12\n15\n". Welches Paar ergibt sich aus first = f.read() gefolgt von second = f.read() auf einem frisch geöffneten Leser?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
"C:\new\tasks.txt" unter Windows die beabsichtigte Datei verfehlen?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
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?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
label;count, aber der standardmäßige CSV-Leser gibt ["label;count"] zurück. Welche Lesereinstellung passt zu dieser Datei?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")
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
try tritt FileNotFoundError auf. Der erste Behandler ist except OSError: print("file problem"), der zweite ist except FileNotFoundError: print("missing"). Was wird ausgegeben?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
except ValueError:-Blocks dieselbe aktive Ausnahme an den aufrufenden Code weiter?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)
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)
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
f.writelines(["red", "blue\n"]) beschrieben und dann erneut im Anfügemodus geöffnet, um "green\n" zu schreiben. Welchen Text enthält sie?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
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?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
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?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
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?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
{"east": 4}["west"] aus?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()
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
try/except ValueError für die Umwandlung stehen?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
class LimitError(ValueError): pass wird ein LimitError ausgelöst. Was geschieht, wenn except ValueError: vor except LimitError: steht?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
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?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
f.readline() am Dateiende zurück?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?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?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
data/menu.txt neben seinem eigenen Speicherort lesen. Welcher Ausdruck erstellt diesen Pfad im Skript?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
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?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
{"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?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
ValueError von int(text) ab. Dieser Behandler gibt missing_name aus, einen Namen, der nie definiert wurde. Was geschieht mit dem neuen NameError?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
"North in der physischen Zeile 2 und endet mit Hall",7 in Zeile 3. Welche Stelle meldet reader.line_num nach dem Lesen?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
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?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
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?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
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?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
"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?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
/srv/course, führt tools/read.py aus und öffnet "../shared/items.txt". Welchen Pfad fordert er an?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
["Vale, East", None, 3]. Welcher Datensatz entsteht, wenn du seinen abschließenden Zeilenabschluss außer Acht lässt?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
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")
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
int() akzeptiert, einschließlich führender Leerzeichen und eines Vorzeichens. Warum sollte er int(text) in try versuchen, statt zuerst text.isdigit() zu verlangen?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
sys.exit("Required file unavailable") innerhalb von Code aus, der durch except Exception: abgedeckt ist. Was geschieht?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
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?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
class ImportDataError(Exception): pass fängt aufrufender Code nur ValueError ab. Was geschieht, wenn seine Hilfsfunktion ImportDataError auslöst?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Hängst du bei deiner eigenen Aufgabe fest? Hausaufgabenhilfe
Schlüsselbegriffe
A
absoluter Pfad
/ auf Unix-ähnlichen Systemen oder einer Laufwerkswurzel unter Windows./Users/maya/data/notes.txt hängt nicht vom aktuellen Arbeitsverzeichnis ab.Akkumulator
errors beginnt bei 0 und erhöht sich jedes Mal um 1, wenn die Schleife einen Datensatz der Fehlerstufe findet.aktuelles Arbeitsverzeichnis
python tools/report.py vom Wurzelverzeichnis des Projekts aus wechselt nicht von selbst in das Verzeichnis tools.Anfügemodus
"a" für Durchlaufmeldungen erhält frühere Durchläufe, aber die Meldung benötigt weiterhin ein eigenes Zeilenumbruchzeichen.AttributeError
"hi".push("!") löst AttributeError aus, weil eine Python-Zeichenkette keine Methode namens push hat.aufrufender Code
Ausnahme
int("many") löst eine Ausnahme aus, bevor die nächste Anweisung in diesem Block ausgeführt wird.Ausnahmebehandler
Ausnahmehierarchie
Ausnahmeverkettung
raise ... from err einen früheren Fehler als direkte Ursache einer neuen Ausnahme.B
Beendigungsstatus
sys.exit("Missing input") gibt die Meldung auf der Fehlerausgabe aus und endet mit dem Beendigungsstatus 1.benutzerdefinierte Ausnahme
Binärmodus
"rb" bezeichnet die Eingabe von Bytes, während die Texteingabe einen Modus wie "r" verwendet.Bindung einer Ausnahme
as einen Namen, sodass sein Typ oder seine Meldung innerhalb dieses Behandlers untersucht werden kann.except ValueError as err: zeigt die Ausgabe von err die Meldung; die Bindung wird danach gelöscht.Byte-Reihenfolgemarkierung
encoding="utf-8-sig" entfernt die anfängliche Markierung, sodass der erste Spaltenname dem beabsichtigten Namen entspricht.C
CSV
"Lopez, Maria",10,8 hat drei Felder, weil sein erstes Komma innerhalb eines Namens in Anführungszeichen steht.CSV-Schreiber
D
Dateiendung
suffix eines Pfads verfügbar.Path("data/sales.csv") ist ".csv", was ein Programm bei der Auswahl von Tabellendateien verwenden kann.Dateimodus
open(), das den erlaubten Zugriff und den Umgang mit vorhandenem Inhalt unter dem Pfad beim Öffnen festlegt."a", um frühere Meldungen zu behalten, während ein neuer Bericht sie mit "w" ersetzen kann.Dateiname ohne letzte Endung
Path("logs/run.txt") ist der Dateiname ohne letzte Endung "run", während der vollständige letzte Name "run.txt" lautet.Dateiobjekt
open() zurückgegebene Objekt, das einem Programm Methoden zum Lesen oder Schreiben einer geöffneten Datei bereitstellt.with open("notes.txt", encoding="utf-8") as f: verweist der Name f auf das Dateiobjekt.Dateiposition
f.read() den verbleibenden Inhalt gelesen hat, gibt ein zweites Lesen eine leere Zeichenkette zurück.Datensatz
Datensatzabschluss
"\r\n".newline="" lässt den CSV-Schreiber seine eigenen Abschlüsse ohne eine zweite Umwandlung bereitstellen.delegierte Ausnahmebehandlung
DictReader
name,score kann mit row["score"] auf eine Zeile zugegriffen werden, auch wenn die Spalten neu angeordnet werden.DictWriter
fieldnames=["product", "stock"] exportiert diese Spalten, wenn ihm passende Wörterbücher übergeben werden.E
Einschließen in Anführungszeichen
"River, West", während eine einfache Aufteilung an Kommas diesen Namen zerlegen würde.else-Klausel
Entfernen von Leerraumzeichen am Rand
line.strip() wird eine Zeile, die nur Leerzeichen und ein Zeilenumbruchzeichen enthält, zu einer leeren Zeichenkette.erneutes Auslösen einer Ausnahme
raise weiter und ermöglicht eine lokale Reaktion, ohne den Fehler als behoben zu behandeln.Erstellen von Verzeichnissen
mkdir(parents=True) kann auch fehlende übergeordnete Verzeichnisse erstellen.output/daily vor dem Schreiben seines Berichts, da das Öffnen einer neuen Ausgabedatei keine Verzeichnisse erstellt.exklusives Erstellen
FileExistsError aus, falls dort bereits eine Datei existiert."x" verhindert, dass ein neu erzeugter Bericht einen Bericht unter demselben Pfad stillschweigend ersetzt.F
fehlendes Feld
None.name,score hat die Zeile Ana einen fehlenden Punktzahlwert; Ana, enthält dagegen eine leere Zeichenkette für die Punktzahl.Fehlerbehandlung auf Datensatzebene
Fehlermeldung
Feld
Feldtrennzeichen
delimiter=";", damit ein Leser name;score in zwei Felder trennt.fieldnames
writeheader() bei einem DictWriter gibt die Namen in der festgelegten Reihenfolge von fieldnames aus.FileExistsError
"x" löst FileExistsError aus, statt seinen Inhalt zu ersetzen.FileNotFoundError
finally-Klausel
G
geschlossene Datei
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
* 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
IsADirectoryError
K
KeyboardInterrupt
except: kann Strg+C abfangen, während except Exception: die Unterbrechung weitergeben lässt.KeyError
row["name"] schlägt fehl, wenn die Kopfzeile der Tabelle stattdessen den Schlüssel "Name" erzeugt hat.Kontextmanager
with-Blocks organisiert, etwa das Bereitstellen des Zugriffs und das Aufräumen.kontrolliertes Scheitern
Kopfzeile
product,stock,price benennt Spalten und sollte nicht als Daten an eine Umwandlung in ganze Zahlen übergeben werden.L
Leeren der Datei
"w" zerstört die alten Datensätze, selbst wenn das Programm nie einen Schreibaufruf erreicht.Logikfehler
N
NameError
P
Path-Objekt
Path("data") / "scores.txt" erstellt einen Ort, den open() direkt akzeptieren kann.PermissionError
Pfad
data/notes.txt bezeichnet eine Textdatei im Datenverzeichnis unter dem aktuellen Arbeitsverzeichnis.physische Zeilennummer
line_num des Lesers bezeichnet die zuletzt gelesene Zeile eines Datensatzes, der sich über zwei Zeilen erstreckt.Puffer
R
raise-Anweisung
raise ValueError("amount must be positive") zurück.relativer Pfad
project/scripts verweist ../data/notes.txt in das benachbarte Datenverzeichnis des Projekts.rohe Zeichenkette
r, sodass umgekehrte Schrägstriche als wörtliche Zeichen erhalten bleiben, statt als gewöhnliche Escape-Sequenzen interpretiert zu werden.r"C:\new\table.txt" erhält die Trennzeichen, die sonst Escape-Sequenzen für Zeilenumbruch und Tabulator beginnen würden.S
spezifischer Ausnahmebehandler
SystemExit
sys.exit() außerhalb des gewöhnlichen Exception-Zweigs ausgelöst.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
Traceback
try-Block
TypeError
"5" und 3 löst TypeError aus, weil die Zeichenkettenaddition keine ganze Zahl als zweiten Operanden akzeptiert.U
UnicodeDecodeError
encoding="utf-8" passt.UTF-8
encoding="utf-8" beim Öffnen einer als UTF-8 gespeicherten Textdatei, damit ihre Buchstaben mit Akzenten korrekt dekodiert werden.Ü
übergeordnete Ausnahmeklasse
übergeordnetes Verzeichnis
parent eines Pfads wählt diesen umschließenden Ort aus.Path("reports/2026/sales.csv") ist das übergeordnete Verzeichnis der Pfad reports/2026.V
Validierung
ValueError
"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
with-Anweisung
with-Block geöffnete Datei wird auch geschlossen, wenn die Umwandlung einer Zeile innerhalb des Blocks einen Fehler auslöst.writerow
writer.writerow(["Ana", 8.5]) für einen Datensatz mit zwei Feldern, keine bereits zusammengefügte Zeichenkette.writerows
writerows() übergeben werden, um mehrere Datensätze mit einem Aufruf zu speichern.Z
Zeichenkodierung
Zeilenfilter
"ERROR" entspricht.Zeilenumbruchzeichen
"\n" geschrieben, markiert einen Zeilenumbruch; die letzte Zeile einer Datei kann ohne Zeilenabschluss sein."\n" endet, fügt ein weiteres Zeilenumbruchzeichen hinzu, sofern der Ausgabeabschluss nicht geändert wird.ZeroDivisionError
zusätzliches Feld
None.Über diese Einheit
Erstelle deine eigenen Lernmaterialien
Mach aus deinen Notizen, Folien und Dokumenten Lernleitfäden, Übungsfragen, Karteikarten und 6 weitere Tools.