Dateien lesen und schreiben · Übung
Text sicher lesen
Ein Pfad beantwortet die Frage „Welche Datei?“. Die nächsten Fragen lauten: „Welche Art von Zugriff?“ und „Wie sollen diese Bytes zu Text werden?“
Hier ist die vollständige Schnittstelle, die diese Lektion aufbaut:
with open(path, "r", encoding="utf-8") as handle:
# read from handle here
Lies die erste Zeile von innen nach außen:
pathist die zu öffnende Datei;"r"bedeutet Lesemodus;encoding="utf-8"gibt an, wie gespeicherte Bytes zu Python-Strings werden;as handlegibt der geöffneten Datei einen vorübergehenden Namen.
Warum with den Dateizugriff verwaltet
Eine geöffnete Datei ist eine Ressource des Betriebssystems. Sie sollte geschlossen werden, wenn die Arbeit fertig ist, auch wenn das Lesen mittendrin fehlschlägt.
Die Anweisung with macht diese Lebensdauer sichtbar. Python öffnet die Datei vor dem eingerückten Block und schließt sie, wenn der Block endet. Auch wenn eine Ausnahme den Block vorzeitig verlässt, wird die Datei geschlossen. Du brauchst kein weit entferntes handle.close(), das durch ein neues return oder einen Fehler versehentlich übersprungen werden könnte.
Das ist ein Kontextmanager: Der von open(...) erzeugte Wert weiß, wie er einen verwalteten Block sicher betritt und verlässt. Später lernst du weitere Kontextmanager kennen. Für jetzt genügt eine kleine, dauerhafte Regel: Wenn ein Dateihandle zu einer einzelnen Operation gehört, lege diese Operation in einen with-Block.
Zeilen lesen, ohne leere Einträge zu behalten
data/books.txt enthält einen Titel pro Zeile und eine absichtliche Leerzeile. Wenn du über das Dateihandle iterierst, erhältst du jede Zeile als Text samt abschließendem Zeilenumbruch. .strip() entfernt den umgebenden Leerraum. Ein leeres Ergebnis sollte nicht zu einem leeren Buchtitel werden.
Baue das Ergebnis mit den Listen- und Schleifenwerkzeugen auf, die du bereits kennst:
books = []
for line in handle:
title = line.strip()
if title:
books.append(title)
Verwende den Parameter path, nicht BOOKS_PATH. Es ist verlockend, auf die Konstante oben in der Datei zuzugreifen. Eine Funktion, die nur eine bestimmte Datei liest, ist aber nicht wiederverwendbar. In den nächsten Kapiteln bekommt diese Funktion mehrere verschiedene Dateien. Schreibe sie so, dass sie das liest, was ihr übergeben wird.
Die Kodierung gehört zur Dateivereinbarung
UTF-8 kann den Nicht-ASCII-Titel Cien años de soledad und gewöhnlichen englischen Text in einer portablen Kodierung darstellen. Wenn du dich auf den Standard eines Computers verlässt, können dieselben Bytes auf verschiedenen Computern unterschiedlich interpretiert werden.
encoding="utf-8" ist keine Fehlerbehebung. Es ist eine ausdrückliche Vereinbarung. Wenn die Bytes einer Datei kein gültiges UTF-8 sind, löst Python UnicodeDecodeError aus. Die nächste Lektion entscheidet, wo dieser erwartete Fehler an der Schnittstelle behandelt wird.
Vervollständige read_books(path) im Projekteditor und reiche anschließend ein.
Wenn du bei der Schleife feststeckst, frage Monty, was line.strip() für eine Zeile zurückgibt, die nur einen Zeilenumbruch enthält. Dieser eine Wert erklärt, warum du die Leerzeile überhaupt behandeln musst.
Was bietet dir die Anweisung with, was ein einfaches open nicht bietet?
Warum solltest du encoding="utf-8" übergeben, statt dich auf den Standard zu verlassen?
Aufgabe
Implementiere read_books(path).
Öffne den übergebenen
pathim ausdrücklich angegebenen Lesemodus mit UTF-8-Kodierung.Verwalte das geöffnete Dateihandle mit einer
with-Anweisung.Gib eine Liste der von umgebendem Leerraum bereinigten, nicht leeren Zeilen in ihrer ursprünglichen Reihenfolge zurück.
Verwende den Parameter; baue weder
BOOKS_PATHnoch die bereitgestellten Titel fest ein.
Lass die anderen Funktionen für spätere Lektionen stehen.