mitmario.dev

Eine Datei schreiben

Python Sandbox 3 Min Lesezeit 5 BeispieleLektion 3 von 8

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

Ein Bericht in eine Datei
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

Überschrieben ohne Rückfrage
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”

Eine Zeile anhängen
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.

Angehängt ohne Zeilenumbruch
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 schreibt in die Datei
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, kostenlos

Zu 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.