Zum Inhalt springen
aviral gupta

// B5.3 · ca. 25 Min. · Einstieg

Dateien lesen und schreiben

Nach dieser Lektion speichern Sie Text in einer Datei und lesen ihn wieder ein: mit dem passenden Modus, der Datei in einem with-Block und dem Zeilenumbruch am Ende jeder Zeile im Griff.

Lektion 3 von 5 in B5 Module, Dateien und Fehler

Danach können Sie

  • Eine Datei im passenden Modus (r, w oder a) in einem with-Block öffnen, mit encoding="utf-8"
  • Eine ganze Datei mit read() lesen oder Zeile für Zeile mit einer for-Schleife, ohne die Zeilenumbrüche
  • Text mit write() schreiben und dabei Zeilenumbrüche und Zahlen selbst umwandeln
  1. Aufwärmen · Aufgabe 1 von 7

    Aufwärmen aus der letzten Lektion: Was gibt das aus?

    print(f"{'pen':<5}|{3:>3}|")
  2. Vorhersagen · Aufgabe 2 von 7

    Sagen Sie es vorher, bevor Sie weiterlesen: Was gibt das aus?

    with open("notes.txt", "w", encoding="utf-8") as f:
        f.write("one")
        f.write("two")
    
    with open("notes.txt", encoding="utf-8") as f:
        print(f.read())
  3. Üben · Aufgabe 3 von 7

    Jeder Schleifendurchlauf öffnet die Datei neu. Setzen Sie den Modus ein, damit beide Wörter in log.txt landen.

    for word in ["red", "green"]:
        with open("log.txt", "____", encoding="utf-8") as f:
            f.write(word + "\n")
    open("log.txt", "", encoding
  4. Üben · Aufgabe 4 von 7

    Jetzt mit "w". Was gibt das aus?

    for word in ["red", "green"]:
        with open("log.txt", "w", encoding="utf-8") as f:
            f.write(word + "\n")
    
    with open("log.txt", encoding="utf-8") as f:
        print(f.read().split())
  5. Üben · Aufgabe 5 von 7

    Ordnen Sie jedem Modus zu, was open damit tut.

  6. Denksport · Aufgabe 6 von 7

    Knobelaufgabe. Was gibt das aus?

    with open("names.txt", "w", encoding="utf-8") as f:
        f.write("Ada\nGrace\n")
    
    with open("names.txt", encoding="utf-8") as f:
        lengths = [len(line) for line in f]
    
    print(lengths)
  7. Anwenden · Aufgabe 7 von 7

    Mini-Aufgabe. Schreiben Sie drei Aufgaben, buy milk, call Ada und water plants, in todo.txt, eine pro Zeile. Öffnen Sie die Datei dann erneut, lesen Sie sie Zeile für Zeile und geben Sie jede Aufgabe nummeriert aus: 1. buy milk. Starten Sie das Programm zweimal: Die Liste darf nicht wachsen.

    Prüfen Sie Ihr Ergebnis anhand dieser Liste

Selbst programmieren

Lesen Sie das ausgearbeitete Beispiel und lösen Sie dann die Übungen. Ihr Code läuft in Ihrem Browser oder auf Ihrem Computer und wird nie hochgeladen.

Ausgearbeitetes Beispiel

Eine Einkaufsliste auf der Festplatte

Das Programm schreibt eine Einkaufsliste mit "w", ergänzt einen Eintrag mit "a" und liest die Datei zweimal: einmal Zeile für Zeile, um die Einträge zu nummerieren, und einmal mit read(), um den rohen Text anzusehen. repr zeigt die Zeilenumbrüche, die write in die Datei geschrieben hat.

main.py

items = ["apples", "bread", "cheese"]

with open("shopping.txt", "w", encoding="utf-8") as f:
    for item in items:
        f.write(item + "\n")

with open("shopping.txt", "a", encoding="utf-8") as f:
    written = f.write("dates\n")
print("appended", written, "characters")

with open("shopping.txt", encoding="utf-8") as f:
    for number, line in enumerate(f, start=1):
        print(f"{number}. {line.strip()}")

with open("shopping.txt", encoding="utf-8") as f:
    text = f.read()
print(repr(text[:13]), len(text.splitlines()), "lines")

Ausführen mit

python main.py

Ausgabe

appended 6 characters
1. apples
2. bread
3. cheese
4. dates
'apples\nbread\n' 4 lines
  • write lieferte 6: die fünf Buchstaben von dates plus den Zeilenumbruch.
  • "a" behielt die drei mit "w" geschriebenen Einträge und hängte dates ans Ende.
  • line.strip() entfernt den Zeilenumbruch, darum stehen keine Leerzeilen zwischen den nummerierten Zeilen.
  • repr(text[:13]) zeigt die ersten beiden Zeilen so, wie sie gespeichert sind, jede mit \n am Ende.
Ändern und ausführen

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser Python herunter (bis zu 6.5 MB) und speichert es im Cache. Ihr Code bleibt auf Ihrem Gerät.

Übungen

Übung 1 von 2

Punktzahlen aus einer Datei

scores.txt (zweiter Reiter) enthält pro Zeile ein Paar name,score. Lesen Sie die Datei und geben Sie zwei Zeilen aus: wie viele Punktzahlen es gibt und ihren Durchschnitt mit einer Nachkommastelle, dann den besten Namen samt Punktzahl. Für die mitgelieferte Datei: 3 scores, average 82.3 und best: ada (90). Die Tests probieren auch andere Dateien, übernehmen Sie also keine festen Zahlen.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser Python herunter (bis zu 6.5 MB) und speichert es im Cache. Ihr Code bleibt auf Ihrem Gerät.

Hinweise
  1. Hinweis 1

    with open("scores.txt", encoding="utf-8") as f: und dann for line in f: liefert eine Zeile nach der anderen.

  2. Hinweis 2

    line.strip().split(",") macht aus "ada,90\n" die Liste ["ada", "90"]. Wandeln Sie die Punktzahl mit int() um.

  3. Hinweis 3

    Sammeln Sie die Paare in einem Dictionary. max nimmt ein key= wie sorted() in Lektion B3.4, also liefert max(scores, key=lambda name: scores[name]) den Namen mit der höchsten Punktzahl, und {average:.1f} rundet auf eine Nachkommastelle.

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

scores: dict[str, int] = {}
with open("scores.txt", encoding="utf-8") as f:
    for line in f:
        name, score = line.strip().split(",")
        scores[name] = int(score)

average = sum(scores.values()) / len(scores)
best = max(scores, key=lambda name: scores[name])
print(f"{len(scores)} scores, average {average:.1f}")
print(f"best: {best} ({scores[best]})")
Auf dem eigenen Computer ausführen

Installieren Sie Python 3.14 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.py

# Read scores.txt: one "name,score" pair per line.
print("3 scores, average 82.3")
print("best: ada (90)")

test_main.py

from learnrun import run_main


def run_with(text):
    with open("scores.txt", encoding="utf-8") as f:
        original = f.read()
    with open("scores.txt", "w", encoding="utf-8") as f:
        f.write(text)
    try:
        return run_main().strip().splitlines()
    finally:
        with open("scores.txt", "w", encoding="utf-8") as f:
            f.write(original)


def test_given_file():
    """Die mitgelieferte Datei ergibt 3 Punktzahlen, Durchschnitt 82.3, beste ada"""
    got = run_main().strip().splitlines()
    assert got == ["3 scores, average 82.3", "best: ada (90)"], f"das Programm gab {got!r} aus"


def test_other_file():
    """Eine andere Datei ergibt ihre eigene Anzahl, ihren Durchschnitt und ihre Beste"""
    got = run_with("lin,70\nmo,95\n")
    assert got == ["2 scores, average 82.5", "best: mo (95)"], f"für lin,70 und mo,95 gab das Programm {got!r} aus"


def test_no_final_newline():
    """Eine Datei ohne Zeilenumbruch in der letzten Zeile funktioniert auch"""
    got = run_with("kim,60\nsam,61")
    assert got == ["2 scores, average 60.5", "best: sam (61)"], f"für kim,60 und sam,61 gab das Programm {got!r} aus"

scores.txt

ada,90
grace,85
alan,72

Unter macOS und Linux tippen Sie python3, wo in diesen Befehlen python steht, wie in der ersten Lektion.

Programm ausführen:

python main.py

Prüfungen ausführen (learnrun.py muss im selben Ordner liegen):

python learnrun.py test
learnrun.py herunterladen

Übung 2 von 2

Eine Liste von Zeilen speichern und laden

Schreiben Sie save_lines(path, lines), das jeden String der Liste in eine eigene Zeile der Datei schreibt und den alten Inhalt ersetzt, und load_lines(path), das die Zeilen als Liste ohne Zeilenumbrüche zurückgibt. save_lines("todo.txt", ["milk", "eggs"]) macht den Dateitext genau zu "milk\neggs\n". Nutzen Sie in beiden with und encoding="utf-8".

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser Python herunter (bis zu 6.5 MB) und speichert es im Cache. Ihr Code bleibt auf Ihrem Gerät.

Hinweise
  1. Hinweis 1

    Der Modus "w" leert die Datei zuerst, ein zweites Speichern ersetzt also das erste. "a" würde anhängen.

  2. Hinweis 2

    write ergänzt keinen Zeilenumbruch: Schreiben Sie line + "\n" für jeden Eintrag.

  3. Hinweis 3

    Entfernen Sie beim Lesen den Umbruch aus jeder Zeile: [line.rstrip("\n") for line in f]. strip() geht auch, entfernt aber auch Leerzeichen an den Enden.

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

def save_lines(path: str, lines: list[str]) -> None:
    with open(path, "w", encoding="utf-8") as f:
        for line in lines:
            f.write(line + "\n")


def load_lines(path: str) -> list[str]:
    with open(path, encoding="utf-8") as f:
        return [line.rstrip("\n") for line in f]


if __name__ == "__main__":
    save_lines("todo.txt", ["milk", "eggs"])
    print(load_lines("todo.txt"))
Auf dem eigenen Computer ausführen

Installieren Sie Python 3.14 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.py

def save_lines(path: str, lines: list[str]) -> None:
    with open(path, "a", encoding="utf-8") as f:
        for line in lines:
            f.write(line)


def load_lines(path: str) -> list[str]:
    with open(path, encoding="utf-8") as f:
        return list(f)


if __name__ == "__main__":
    save_lines("todo.txt", ["milk", "eggs"])
    print(load_lines("todo.txt"))

test_main.py

from main import load_lines, save_lines


def test_file_text():
    """save_lines schreibt eine Zeile pro Eintrag, jede mit Zeilenumbruch am Ende"""
    save_lines("t1.txt", ["milk", "eggs"])
    with open("t1.txt", encoding="utf-8") as f:
        text = f.read()
    assert text == "milk\neggs\n", f"die Datei enthält {text!r}, erwartet war 'milk\\neggs\\n'"


def test_round_trip():
    """load_lines liefert genau das Gespeicherte zurück, auch Umlaute"""
    lines = ["Grüße", "tea for two", "42"]
    save_lines("t2.txt", lines)
    got = load_lines("t2.txt")
    assert got == lines, f"load_lines gab {got!r} zurück, erwartet war {lines!r}"


def test_replaces():
    """Erneutes Speichern ersetzt die alten Zeilen"""
    save_lines("t3.txt", ["old"])
    save_lines("t3.txt", ["new"])
    got = load_lines("t3.txt")
    assert got == ["new"], f"nach dem Speichern von ['old'] und dann ['new'] gab load_lines {got!r} zurück"

Unter macOS und Linux tippen Sie python3, wo in diesen Befehlen python steht, wie in der ersten Lektion.

Programm ausführen:

python main.py

Prüfungen ausführen (learnrun.py muss im selben Ordner liegen):

python learnrun.py test
learnrun.py herunterladen

Häufige Fehler

Eine Datei lesen, die es nicht gibt

with open("scores.txt", encoding="utf-8") as f:
    print(f.read())

Was Python ausgibt

No such file or directory: 'scores.txt'

Warum, und die Lösung

Die ganze Zeile lautet FileNotFoundError: [Errno 2] No such file or directory: 'scores.txt' (im Browser steht 44 statt 2). Der Modus "r" legt nie eine Datei an. Prüfen Sie die Schreibweise und ob die Datei in dem Ordner liegt, in dem das Programm läuft; auf Ihrem Rechner ist das der Ordner, aus dem Sie python gestartet haben.

Eine Zahl schreiben

count = 42
with open("count.txt", "w", encoding="utf-8") as f:
    f.write(count)

Was Python ausgibt

TypeError: write() argument must be str, not int

Warum, und die Lösung

write nimmt nur Strings, anders als print. Wandeln Sie zuerst um und setzen Sie den Zeilenumbruch selbst: f.write(str(count) + "\n") oder f.write(f"{count}\n"). Beim Zurücklesen macht int(line) aus dem Text wieder eine Zahl.

In eine zum Lesen geöffnete Datei schreiben

with open("notes.txt", "w", encoding="utf-8") as f:
    f.write("first line\n")

with open("notes.txt", encoding="utf-8") as f:
    f.write("second line\n")

Was Python ausgibt

io.UnsupportedOperation: not writable

Warum, und die Lösung

Ohne Modus nimmt open "r", und das liest nur. Um eine Zeile anzuhängen, öffnen Sie mit "a"; um den Inhalt zu ersetzen, mit "w".

Python im Browser: Pyodide 314.0.7, MPL-2.0. Lizenz und Quellcode

Abschlussquiz

5 Fragen, ohne Hinweise. Ab 80 % ist die Lektion abgeschlossen.

Erledigen Sie zuerst alle Aufgaben oben, um das Abschlussquiz freizuschalten.

Problem melden

Etwas ist falsch oder unklar? Beschreiben Sie es kurz, dann wird es geprüft und korrigiert.

#

Mindestens 20 Zeichen.

Nur, wenn Sie eine Antwort wünschen.

Kernideen

open, Modi und with

open(name, mode, encoding="utf-8") liefert ein Dateiobjekt. Der Modus sagt, was Sie vorhaben: "r" liest und ist der Standard; "w" schreibt und leert die Datei vorher, legt sie bei Bedarf an; "a" hängt ans Ende an und behält den Inhalt. Geben Sie immer encoding="utf-8" an, sonst hängt die Kodierung vom Rechner ab, und "Grüße" übersteht es vielleicht nicht. Öffnen Sie Dateien in einem with-Block: Endet er, wird die Datei geschlossen, auch nach einem Fehler darin.

Lesen: read() oder eine Schleife

f.read() liefert die ganze Datei als einen String; ein zweiter Aufruf liefert "", weil das Dateiende erreicht ist. for line in f: liefert eine Zeile nach der anderen, auch bei riesigen Dateien. Jede Zeile behält am Ende ihren Zeilenumbruch "\n", außer eventuell die letzte, darum zeigte print(line) Leerzeilen dazwischen. line.strip() entfernt den Umbruch und Leerzeichen an beiden Enden. text.splitlines() teilt einen ganzen String in Zeilen ohne Umbrüche.

Schreiben: write() ergänzt nichts

f.write(text) schreibt genau den übergebenen String und liefert, wie viele Zeichen es geschrieben hat. Anders als print hängt es keinen Zeilenumbruch an: Zweimal write mit "one" und "two" ergibt onetwo. Setzen Sie "\n" selbst ans Ende jeder Zeile. write nimmt nur Strings: Wandeln Sie eine Zahl vorher mit str(n) oder einem f-String um. Im Browser liegen Dateien im Speicher, und jeder Lauf beginnt nur mit den Dateien aus den Tabs; auf Ihrem Rechner sind es echte Dateien.

Quellen

Zuletzt geprüft am 29. September 2026