Menu

Python-Dateiverarbeitung: Dateien sicher lesen, schreiben und anhängen

Wie du Dateien in Python liest und schreibst — die with-Anweisung, Text vs. Binary und die sicherere moderne pfadbasierte API.

Dateien sind einfach Strings mit einem Pfad

Die meisten Programme müssen irgendwann eine Datei lesen oder schreiben — Konfigurationen, Nutzerdaten, Logs, CSV-Exports, kleine Caches. Python hält das einfach mit einer einzigen eingebauten Funktion, open(), plus einem with-Block, damit alles sauber schließt.

Gehen wir die häufigen Fälle durch.

Eine ganze Datei lesen

Das einfachste Lesen:

with open("notes.txt") as f:
    contents = f.read()

print(contents)

open("notes.txt") öffnet die Datei zum Lesen (Standard). Der with-Block sorgt dafür, dass Python die Datei beim Verlassen schließt — auch bei Ausnahmen. Einmal geschlossen, kannst du f nicht mehr nutzen; der Text lebt in contents.

contents ist ein einzelner String mit der ganzen Datei. Okay für kleine Dateien; schlecht für ein 2 GB großes Log.

Zeile für Zeile lesen

Für größere Dateien iterier, statt alles in den Speicher zu laden:

with open("big.log") as f:
    for line in f:
        if "ERROR" in line:
            print(line.strip())

Jede Iteration liefert eine Zeile inklusive des abschließenden Zeilenumbruchs — deshalb taucht .strip() so oft auf. Willst du eine Liste von Zeilen, macht f.readlines() das, aber meistens willst du die direkte Iteration.

Eine Datei schreiben

Zum Schreiben übergibst du den Modus als zweites Argument:

with open("output.txt", "w") as f:
    f.write("first line\n")
    f.write("second line\n")

Zwei Punkte:

  • "w" überschreibt. Existiert output.txt schon, ist ihr Inhalt weg, sobald open läuft.
  • Zeilenumbrüche musst du selbst setzen. f.write("hello") schreibt genau diese fünf Zeichen — kein Zeilenumbruch.

Zum Anhängen statt Überschreiben:

with open("output.txt", "a") as f:
    f.write("another line\n")

Du kannst mit writelines mehrere Zeilen auf einmal reinfüttern:

lines = ["a\n", "b\n", "c\n"]
with open("letters.txt", "w") as f:
    f.writelines(lines)

Gleiche Regel: du lieferst die Zeilenumbrüche.

print hat ein file-Argument, eine einfache Art zu schreiben, ohne manuelle Zeilenumbrüche:

with open("log.txt", "w") as f:
    print("started", file=f)
    print("finished", file=f)

Jedes print schreibt seine Argumente plus einen Zeilenumbruch. Für lockere Ausgabe ist das oft die angenehmste Form.

Text vs. Binärmodus

Standardmäßig ist open im Textmodus. Python dekodiert Bytes zu Strings (auf modernen Plattformen standardmäßig UTF-8) und übersetzt Zeilenumbrüche.

Für Bilder, PDFs, kompilierte Dateien oder alles, das kein Text ist, öffne im Binärmodus, indem du "b" in den Modus einfügst:

with open("image.png", "rb") as f:
    data = f.read()

print(len(data))  # number of bytes

with open("image_copy.png", "wb") as f:
    f.write(data)

Im Binärmodus bekommst du bytes-Objekte statt str, und Python lässt Zeilenumbrüche in Ruhe.

Encoding angeben

Für Textdateien: sei beim Encoding explizit. UTF-8 ist 2026 fast immer richtig:

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

Hast du mit Alt-Dateien aus einer reinen Windows-Umgebung zu tun, tauchen auch cp1252 oder latin-1 auf. Falsch geraten bedeutet verstümmelte Zeichen oder einen UnicodeDecodeError.

pathlib: die moderne Art, mit Pfaden umzugehen

Das Modul pathlib der Standardbibliothek bietet eine angenehmere API als rohe Strings:

from pathlib import Path

path = Path("notes.txt")

# Simple read and write.
contents = path.read_text(encoding="utf-8")
path.write_text("new contents\n", encoding="utf-8")

# Build paths without worrying about / vs \.
data_dir = Path("data")
log_path = data_dir / "today.log"

print(log_path)
print(log_path.exists())
print(log_path.suffix)       # ".log"
print(log_path.stem)         # "today"
print(log_path.parent)       # "data"

Path.read_text() und write_text() sind Abkürzungen für das with open(...) as f-Muster, wenn du alles auf einmal lesen oder schreiben willst. Für Zeile-für-Zeile nutzt du weiterhin open oder path.open().

Ein kleines End-to-End-Beispiel

Eine Liste von Einträgen aus einer Datei lesen, filtern und das Ergebnis in eine andere Datei schreiben:

from pathlib import Path

source = Path("items.txt")
destination = Path("filtered.txt")

items = source.read_text().splitlines()
kept = [item for item in items if item and not item.startswith("#")]

destination.write_text("\n".join(kept) + "\n")

print(f"Kept {len(kept)} items out of {len(items)}")

splitlines() ist der zeilenorientierte Partner zu join. Er trennt an Zeilenumbrüchen, ohne sie zu behalten — praktisch, wenn du die Teile ohnehin wieder zusammenfügst.

Wenn etwas schiefgeht

Eine nicht existierende Datei zu öffnen wirft FileNotFoundError. Eine Datei zu lesen, für die du keine Berechtigung hast, wirft PermissionError. Beide sind Unterklassen von OSError, das wiederum Unterklasse von Exception ist — über ordentliche Ausnahmebehandlung reden wir auf der nächsten Seite.

Für jetzt ein kleiner Vorgeschmack auf Fehlerbehandlung:

from pathlib import Path

path = Path("maybe.txt")

try:
    contents = path.read_text()
except FileNotFoundError:
    print("File doesn't exist — starting fresh.")
    contents = ""

print(repr(contents))

Schlüsselgewohnheiten

  • Nutz immer with open(...) statt rohem open + manuellem Schließen.
  • Übergib immer encoding= für Textdateien; standardmäßig UTF-8.
  • Iterier große Dateien Zeile für Zeile; kein .read() des Ganzen.
  • Für Pfade und übliche Lese-/Schreibmuster nimm pathlib — es spart dir viel String-Akrobatik.

Als Nächstes: JSON. Die meisten echten Textdateien sind keine reinen Zeilen — sie sind strukturiert, und JSON ist die häufigste Form. Dieselben with open(...)-Gewohnheiten übertragen sich direkt.

Häufig gestellte Fragen

Wie lese ich eine Datei in Python?

Nutz open() mit der with-Anweisung, die die Datei automatisch schließt. with open('file.txt') as f: contents = f.read() liest die ganze Datei in einen String. Für Zeile für Zeile: schleif direkt über das Dateiobjekt: for line in f:.

Was ist der Unterschied zwischen den Open-Modi 'r', 'w' und 'a'?

'r' ist Lesen (Standard). 'w' ist Schreiben — legt die Datei an oder kürzt sie, falls vorhanden. 'a' ist Anhängen — fügt ans Ende an, ohne das Bestehende zu löschen. Füge 'b' für Binärmodus hinzu oder '+' für Lesen+Schreiben.

Warum sollte ich with open statt reinem open nutzen?

Die with-Anweisung garantiert, dass die Datei geschlossen wird, auch wenn mittendrin ein Fehler passiert. Ohne with musst du .close() selbst aufrufen und daran auch in Fehlerpfaden denken. with ist sicherer und kürzer.

Lerne mit Coddy zu programmieren

LOS GEHT'S