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. Existiertoutput.txtschon, ist ihr Inhalt weg, sobaldopenlä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 in eine Datei
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 rohemopen+ 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?
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.