Abschnitt 11 · Lektion 3
Eine Datei schreiben
Ein Bericht, den man am Monatsende verschickt, gehört in eine Datei und nicht ins Terminal. Was im
Terminal steht, ist weg, sobald man es schließt. Für eine schnelle Antwort reicht das auch. Eine
Liste, die ein zweites Programm weiterverarbeiten soll, oder ein Protokoll darüber, wann ein
Werkzeug gelaufen ist, braucht dagegen eine Datei. Geschrieben wird mit demselben open wie beim
Lesen, nur mit einer Angabe mehr.
Eine Datei anlegen
with open("bericht.txt", "w", encoding="utf-8") as datei:
datei.write("Kaffeekasse Oktober\n")
datei.write("Eingezahlt: 23.00 Euro\n")
with open("bericht.txt", encoding="utf-8") as datei:
print(datei.read(), end="") Das zweite Argument von open ist der Modus (mode), und "w" steht für write, schreiben. Ohne
diese Angabe gilt "r", read. Deshalb kam sie beim Lesen bisher nicht vor.
datei.write(…) schreibt den Text, den es bekommt, und zwar genau den. Weil write nicht von sich
aus einen Zeilenumbruch hinzufügt, steht er als \n am Ende jeder Zeile.
Die Kodierung gibst du aus demselben Grund an wie beim Lesen. Hier ist sie sogar noch wichtiger, denn was mit der falschen Kodierung geschrieben wurde, liest jedes andere Programm falsch.
In den letzten zwei Zeilen wird die Datei zur Kontrolle wieder eingelesen. Im Terminal geht das
kürzer, mit cat bericht.txt aus der Befehlsleiste. cat gibt eine Datei so aus, wie sie ist.
“w” fragt nicht
Kaffeekasse September
Eingezahlt: 31.00 Euro
Ausgegeben: 12.49 Euro with open("bericht.txt", encoding="utf-8") as datei:
print(datei.read())
with open("bericht.txt", "w", encoding="utf-8") as datei:
datei.write("Kaffeekasse Oktober\n")
with open("bericht.txt", encoding="utf-8") as datei:
print(datei.read(), end="") Hier gibt es bericht.txt schon, mit dem Bericht vom September. Der wird zuerst angezeigt, und dann
wird die Datei mit "w" geöffnet. In diesem Moment ist der alte Inhalt weg, noch bevor die erste
neue Zeile geschrieben ist. Kein Hinweis, keine Rückfrage, kein Papierkorb. Übrig bleibt die eine
neue Zeile.
Für einen Bericht ist das richtig. Er wird jedes Mal neu geschrieben, und der vom letzten Monat soll
nicht darunter stehen bleiben. Gefährlich wird es bei einer Datei, die etwas sammelt. Wenn du dein
Protokoll mit "w" öffnest, hast du danach ein Protokoll mit genau einer Zeile, und alles davor ist
ohne Meldung verschwunden.
Anhängen mit “a”
01.09.2026: Bericht geschrieben
01.10.2026: Bericht geschrieben with open("protokoll.txt", "a", encoding="utf-8") as datei:
datei.write("01.11.2026: Bericht geschrieben\n")
with open("protokoll.txt", encoding="utf-8") as datei:
print(datei.read(), end="") "a" steht für append, anhängen. Die Datei bleibt, wie sie ist, und was man schreibt, kommt ans
Ende. Gibt es sie noch nicht, wird sie angelegt, genau wie bei "w". Für ein Protokoll ist das der
richtige Modus, weil bei jedem Lauf eine Zeile dazukommt, während die alten stehen bleiben.
01.09.2026: Bericht geschrieben for datum in ["01.10.2026", "01.11.2026"]:
with open("protokoll.txt", "a", encoding="utf-8") as datei:
datei.write(datum + ": Bericht geschrieben")
with open("protokoll.txt", encoding="utf-8") as datei:
print(datei.read()) Hier fehlt das \n. Beim ersten Mal fällt das nicht auf, die Zeile steht ja in der Datei. Erst beim
nächsten Anhängen klebt die neue Zeile an der alten, weil mit "a" genau dort weitergeschrieben
wird, wo die Datei aufhört.
Die Schleife hängt zweimal an, wie bei zwei Läufen hintereinander, und die beiden neuen Einträge stehen danach in einer einzigen langen Zeile. Eine Textdatei endet deshalb immer mit einem Zeilenumbruch, auch nach der letzten Zeile.
print kann auch in Dateien schreiben
einzahlungen = {"Aylin": 10.0, "Mia": 8.0, "Ole": 5.0}
with open("bericht.txt", "w", encoding="utf-8") as datei:
print("Kaffeekasse Oktober", file=datei)
for name, betrag in einzahlungen.items():
print(f"{name:<8}{betrag:6.2f}", file=datei)
with open("bericht.txt", encoding="utf-8") as datei:
print(datei.read(), end="") print hat einen Parameter mit Standardwert, der bisher nie aufgefallen ist, nämlich file. Ohne
Angabe geht die Ausgabe ins Terminal, mit file=datei in die Datei. Alles andere bleibt, wie du es
kennst. Der Zeilenumbruch kommt von selbst, mehrere Werte werden mit einem Leerzeichen getrennt, und
f-Strings mit Formatangaben gehen genauso.
Hast du ein Programm, das einen Bericht ins Terminal schreibt, wird daraus ganz leicht eine Datei.
Du öffnest die Datei und gibst jedem print ein file=datei mit. Mehr nicht.
Für den einfachsten Fall gibt es wie beim Lesen eine Kurzform.
Path("bericht.txt").write_text(text, encoding="utf-8") schreibt einen ganzen Text auf einmal und
überschreibt dabei, was vorher drinstand. Zum Anhängen gibt es keine Kurzform, dafür bleibt es bei
open mit "a".
Was die Aufgabe will
Ein Programm rechnet einmal in der Woche das Haushaltsbuch zusammen und gibt den Bericht bisher im Terminal aus. Künftig soll er in einer Datei liegen, die jede Woche neu entsteht. In einer zweiten Datei soll festgehalten werden, wann welcher Bericht geschrieben wurde.
Zum Mitnehmen
Mit open("bericht.txt", "w", encoding="utf-8") wird eine Datei angelegt oder ohne Rückfrage überschrieben. Mit "a" statt "w" kommt das Neue hinten dran. write() schreibt nur den Text, den es bekommt, einen Zeilenumbruch also nur, wenn \n darin steht. print(..., file=datei) hängt ihn von selbst an.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.
Was in dieser Lektion steckt
-
Artikel mit 5 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe, dein Code läuft auf einem Server
Öffnet sich mit dem Basis Konto.