Dateien lesen und schreiben · Übung
Anhängen, ohne zu löschen
reading_report.txt beantwortet die Frage „Was gilt jetzt?“. Die Verlaufsdatei beantwortet eine andere Frage: „Welche erfolgreichen Programmläufe haben stattgefunden?“
Unterschiedliche Bedeutungen brauchen unterschiedliche Modi.
Anhängen beginnt am Ende
Implementiere diese kleine Schnittstelle:
def append_history(path, count):
with open(path, "a", encoding="utf-8") as handle:
handle.write(f"Recorded {count} books.\n")
Der Modus "a" erstellt die Datei, wenn sie fehlt. Wenn sie existiert, geht jeder Schreibvorgang ans Ende, statt frühere Inhalte zu ersetzen.
Setze eine Testdatei zurück und ändere dann für den zweiten Schreibvorgang einen Buchstaben:
Das erste Öffnen lässt das Experiment aus einem bekannten Zustand starten. Das zweite bewahrt die vorhandene Zeile und fügt eine weitere hinzu. "w" und "a" unterscheiden sich durch ein einziges Zeichen und durch alles, was dieses Zeichen bedeutet. Lösche append-demo.txt, wenn du fertig bist; es ist eine Testdatei, kein Bestandteil des Projekts.
Die Funktion schreibt einen vollständigen Eintrag einschließlich seines Zeilenumbruchs in einem Aufruf. Dadurch bleiben die Grenzen der Einträge sichtbar. Eine spätere Version könnte ein Datum oder einen Quellnamen aufzeichnen. Uhren würden das heutige Projekt und seine Prüfung aber nichtdeterministisch machen. Dieses Kapitel hält nur die stabile Tatsache fest, die es tatsächlich kennt: die Anzahl der von diesem Programmlauf verarbeiteten Bücher.
Ersetzen und Bewahren sind Entscheidungen
Die wichtige Erkenntnis lautet nicht „Anhängen ist sicherer als Schreiben“. Das stimmt nicht.
Verwende
"w", wenn die ganze Datei ein einzelnes ersetzbares Ergebnis ist.Verwende
"a", wenn vorhandene vollständige Einträge zur Bedeutung der Datei gehören.
Jeden neuen Bericht anzuhängen würde mehrere Überschriften und mehrere aktuelle Anzahlen in einer Datei hinterlassen, die einen einzigen aktuellen Bericht verspricht. Den Verlauf zu ersetzen würde unbemerkt genau die Nachweise zerstören, die er bewahren soll.
Vervollständige vor der Wahl eines Modus diesen Satz: „Diese Datei stellt … dar.“ Der passende Modus ergibt sich oft direkt daraus.
Den erfolgreichen Ablauf vervollständigen
Nachdem main() den aktuellen Bericht geschrieben hat, hänge einen Verlaufseintrag an und ändere die Erfolgsmeldung in:
Wrote reading_report.txt and recorded 4 books.
Diese Werte müssen aus dem tatsächlichen Pfad und der tatsächlichen Anzahl stammen. Behalte die beiden Fehlerbehandlungen vor allen Schreibvorgängen bei. Ein fehlgeschlagener Lesevorgang sollte keinen Bericht oder Verlaufseintrag erzeugen, der erfolgreich aussieht.
Welche Kombination passt zur Bedeutung der Dateien?
Prüfe das genauso wie den Bericht: Führe das Programm zweimal aus und öffne reading_history.txt. Du solltest zwei Einträge sehen, nicht einen. Führe es dann ein drittes Mal aus und prüfe, ob du drei Einträge in ihrer zeitlichen Reihenfolge siehst. Ein Verlauf, der immer nur den letzten Lauf enthält, hat seine Aufgabe vergessen.
Aufgabe
Vervollständige den erfolgreichen Ablauf des Journals.
Implementiere
append_history(path, count)mit einerwith-Anweisung, dem ausdrücklich angegebenen Modus"a"und UTF-8.Hänge genau
Recorded N books.\nmit der übergebenen Anzahl an.Nachdem
main()den aktuellen Bericht geschrieben hat, muss es einen Verlaufseintrag anhängen.Gib
Wrote reading_report.txt and recorded N books.mit dem tatsächlichen Berichtspfad und der tatsächlichen Anzahl aus.Behalte das vorhandene eng begrenzte Fehlerverhalten bei; ein fehlgeschlagener Lesevorgang darf nicht als Erfolg aufgezeichnet werden.