0%

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:

  • path ist die zu öffnende Datei;

  • "r" bedeutet Lesemodus;

  • encoding="utf-8" gibt an, wie gespeicherte Bytes zu Python-Strings werden;

  • as handle gibt 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 path im 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_PATH noch die bereitgestellten Titel fest ein.

Lass die anderen Funktionen für spätere Lektionen stehen.