Zum Inhalt springen
Python Anfänger 2 min

Dateien lesen und schreiben in Python

Lerne, wie du in Python Dateien oeffnest, liest, schreibst und mit verschiedenen Formaten wie CSV und JSON arbeitest -- inklusive Best Practices mit dem with-Statement.

Aktualisiert:

Warum Dateien?

Programme arbeiten mit Daten — aber was passiert, wenn du das Programm beendest? Ohne Dateien sind alle Daten weg. Dateien ermoeglichten es dir, Daten dauerhaft zu speichern und spaeter wieder zu laden.

Typische Anwendungsfaelle:

  • Konfigurationsdateien lesen (Einstellungen deiner App)
  • Benutzerdaten speichern (Notizen, Highscores, Kontakte)
  • Logdateien schreiben (was ist im Programm passiert?)
  • Daten austauschen (CSV-Export fuer Excel, JSON fuer APIs)
# Stell dir vor: Dein Programm speichert Notizen
notizen = ["Einkaufen gehen", "Python lernen", "Sport machen"]

# Ohne Dateien: Alles weg nach Programmende!
# Mit Dateien: Daten bleiben erhalten

Die open() Funktion

Die eingebaute Funktion open() ist dein Tor zur Dateiwelt. Sie oeffnet eine Datei und gibt ein Dateiobjekt zurueck, mit dem du arbeiten kannst.

# Grundsyntax
datei = open("meine_datei.txt", "r")
# ... mit der Datei arbeiten ...
datei.close()  # Wichtig: Datei wieder schliessen!

Dateimodi

Der zweite Parameter bestimmt, was du mit der Datei machen willst:

ModusBedeutungDatei existiert nicht?
"r"Read — Lesen (Standard)Fehler!
"w"Write — Schreiben (ueberschreibt!)Wird erstellt
"a"Append — AnhaengenWird erstellt
"x"Exclusive — Erstellen (nur wenn neu)Wird erstellt, Fehler wenn existiert
# Lesen -- Datei muss existieren
datei = open("daten.txt", "r")

# Schreiben -- ACHTUNG: Inhalt wird ueberschrieben!
datei = open("daten.txt", "w")

# Anhaengen -- fuegt am Ende hinzu
datei = open("daten.txt", "a")

# Exklusiv erstellen -- Fehler wenn Datei schon existiert
datei = open("neue_datei.txt", "x")

Das with-Statement — immer verwenden!

Das groesste Problem mit open() und close(): Was passiert, wenn zwischen dem Oeffnen und Schliessen ein Fehler auftritt? Dann wird close() nie aufgerufen und die Datei bleibt gesperrt.

Die Loesung: Das with-Statement (Context Manager). Es schliesst die Datei automatisch, egal was passiert:

# SO solltest du es IMMER machen:
with open("meine_datei.txt", "r") as datei:
    inhalt = datei.read()
    print(inhalt)
# Hier ist die Datei automatisch geschlossen!

# NICHT so (veraltet und fehleranfaellig):
datei = open("meine_datei.txt", "r")
inhalt = datei.read()
datei.close()

Merke dir: Verwende immer with open(...) as ...: — es gibt keinen guten Grund, es nicht zu tun.


Textdateien lesen

Es gibt drei Methoden, um Text aus einer Datei zu lesen:

read() — Alles auf einmal

with open("gedicht.txt", "r") as datei:
    gesamter_text = datei.read()
    print(gesamter_text)

read() gibt den gesamten Inhalt als einen einzigen String zurueck. Bei grossen Dateien kann das viel Speicher verbrauchen.

readline() — Zeile fuer Zeile

with open("gedicht.txt", "r") as datei:
    erste_zeile = datei.readline()
    zweite_zeile = datei.readline()
    print(erste_zeile)
    print(zweite_zeile)

Jeder Aufruf von readline() liest die naechste Zeile. Am Dateiende gibt es einen leeren String "" zurueck.

readlines() — Alle Zeilen als Liste

with open("gedicht.txt", "r") as datei:
    alle_zeilen = datei.readlines()
    print(alle_zeilen)
    # ['Erste Zeile\n', 'Zweite Zeile\n', 'Dritte Zeile\n']

Die eleganteste Methode: Ueber die Datei iterieren

with open("gedicht.txt", "r") as datei:
    for zeile in datei:
        print(zeile.strip())  # strip() entfernt \n am Ende

Das ist speichereffizient, weil immer nur eine Zeile im Speicher liegt — perfekt fuer grosse Dateien!


Textdateien schreiben

write() — Text schreiben

with open("ausgabe.txt", "w") as datei:
    datei.write("Hallo Welt!\n")
    datei.write("Dies ist Zeile 2.\n")
    datei.write("Und Zeile 3.\n")

Wichtig: write() fuegt keinen automatischen Zeilenumbruch hinzu. Du musst \n selbst anhaengen!

writelines() — Liste von Strings schreiben

zeilen = ["Apfel\n", "Birne\n", "Kirsche\n"]

with open("fruechte.txt", "w") as datei:
    datei.writelines(zeilen)

Auch writelines() fuegt keine Zeilenumbrueche hinzu — du musst sie in den Strings selbst haben.

Trick: print() in Dateien umleiten

with open("ausgabe.txt", "w") as datei:
    print("Das kommt in die Datei!", file=datei)
    print("Auch das.", file=datei)
    print(f"Ergebnis: {42 * 3}", file=datei)

Mit dem file-Parameter von print() kannst du die Ausgabe direkt in eine Datei umleiten — inklusive automatischem Zeilenumbruch!


Dateien anhaengen mit dem "a"-Modus

Wenn du Daten hinzufuegen willst, ohne den bestehenden Inhalt zu loeschen, nutze den Append-Modus:

# Logbuch fuehren
from datetime import datetime

def log_eintrag(nachricht):
    with open("logbuch.txt", "a") as log:
        zeitstempel = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log.write(f"[{zeitstempel}] {nachricht}\n")

log_eintrag("Programm gestartet")
log_eintrag("Benutzer eingeloggt")
log_eintrag("Daten gespeichert")

Das Logbuch waechst mit jedem Aufruf:

[2026-02-10 14:30:01] Programm gestartet
[2026-02-10 14:30:02] Benutzer eingeloggt
[2026-02-10 14:30:05] Daten gespeichert

Encoding — Zeichenkodierung beachten

Text wird in Dateien als Bytes gespeichert. Damit Umlaute (ae, oe, ue) und Sonderzeichen korrekt funktionieren, musst du die richtige Zeichenkodierung angeben:

# Immer UTF-8 verwenden -- der moderne Standard
with open("deutsch.txt", "w", encoding="utf-8") as datei:
    datei.write("Gruesse aus Muenchen!\n")
    datei.write("Schoene Ueberraschung!\n")

with open("deutsch.txt", "r", encoding="utf-8") as datei:
    print(datei.read())

Ohne encoding="utf-8" verwendet Python die Standardkodierung deines Betriebssystems, was auf Windows oft cp1252 ist. Das fuehrt zu Problemen, wenn du Dateien zwischen Systemen austauschst. Gewoehn dir an, immer encoding="utf-8" anzugeben.


CSV-Dateien mit dem csv-Modul

CSV (Comma-Separated Values) ist ein einfaches Tabellenformat — perfekt fuer strukturierte Daten.

CSV schreiben

import csv

schueler = [
    ["Name", "Alter", "Note"],
    ["Anna", 16, 1.3],
    ["Ben", 17, 2.0],
    ["Clara", 16, 1.7],
]

with open("schueler.csv", "w", encoding="utf-8", newline="") as datei:
    writer = csv.writer(datei)
    writer.writerows(schueler)

Wichtig: newline="" verhindert leere Zeilen auf Windows!

CSV lesen

import csv

with open("schueler.csv", "r", encoding="utf-8") as datei:
    reader = csv.reader(datei)
    for zeile in reader:
        print(zeile)
# ['Name', 'Alter', 'Note']
# ['Anna', '16', '1.3']
# ...

CSV mit Woerterbuch (DictReader / DictWriter)

import csv

# Lesen als Woerterbuch -- viel uebersichtlicher!
with open("schueler.csv", "r", encoding="utf-8") as datei:
    reader = csv.DictReader(datei)
    for zeile in reader:
        print(f"{zeile['Name']} hat die Note {zeile['Note']}")

JSON-Dateien mit dem json-Modul

JSON (JavaScript Object Notation) ist das Standardformat fuer den Datenaustausch im Web. Python-Dicts und JSON passen perfekt zusammen.

JSON schreiben

import json

einstellungen = {
    "benutzername": "max_mustermann",
    "design": "dunkel",
    "sprache": "de",
    "benachrichtigungen": True,
    "favoriten": ["Python", "JavaScript", "Rust"]
}

with open("config.json", "w", encoding="utf-8") as datei:
    json.dump(einstellungen, datei, indent=4, ensure_ascii=False)
  • indent=4 sorgt fuer huebsche Formatierung
  • ensure_ascii=False erlaubt Umlaute in der Ausgabe

JSON lesen

import json

with open("config.json", "r", encoding="utf-8") as datei:
    einstellungen = json.load(datei)

print(einstellungen["benutzername"])  # max_mustermann
print(einstellungen["favoriten"])     # ['Python', 'JavaScript', 'Rust']

JSON und Strings

import json

# Python-Objekt -> JSON-String
daten = {"name": "Anna", "alter": 25}
json_string = json.dumps(daten, indent=2)
print(json_string)

# JSON-String -> Python-Objekt
wieder_daten = json.loads(json_string)
print(wieder_daten["name"])  # Anna

Merke: dump/load arbeiten mit Dateien, dumps/loads arbeiten mit Strings (das “s” steht fuer “string”).


pathlib.Path — Moderner Umgang mit Pfaden

Das pathlib-Modul ist der moderne Weg, mit Dateipfaden zu arbeiten. Es ist objektorientiert und plattformunabhaengig.

from pathlib import Path

# Pfad erstellen
pfad = Path("daten") / "projekte" / "notizen.txt"
print(pfad)  # daten/projekte/notizen.txt (bzw. daten\projekte\notizen.txt auf Windows)

# Nuetzliche Eigenschaften
print(pfad.name)       # notizen.txt
print(pfad.stem)       # notizen
print(pfad.suffix)     # .txt
print(pfad.parent)     # daten/projekte

# Pruefen, ob Datei/Ordner existiert
print(pfad.exists())   # True oder False
print(pfad.is_file())  # True oder False
print(pfad.is_dir())   # True oder False

Dateien mit pathlib lesen und schreiben

from pathlib import Path

pfad = Path("notizen.txt")

# Schreiben (ueberschreibt)
pfad.write_text("Meine erste Notiz\n", encoding="utf-8")

# Lesen
inhalt = pfad.read_text(encoding="utf-8")
print(inhalt)

# Ordner erstellen (auch verschachtelt)
ordner = Path("daten") / "backup"
ordner.mkdir(parents=True, exist_ok=True)

Dateien in einem Ordner auflisten

from pathlib import Path

ordner = Path(".")  # Aktueller Ordner

# Alle .py-Dateien finden
for py_datei in ordner.glob("*.py"):
    print(py_datei.name)

# Rekursiv in Unterordnern suchen
for py_datei in ordner.rglob("*.py"):
    print(py_datei)

Praxis: Notizen-App

Lass uns eine kleine Notizen-App bauen, die Notizen in einer Datei speichert:

import json
from pathlib import Path
from datetime import datetime

NOTIZEN_DATEI = Path("notizen.json")


def notizen_laden():
    """Laedt Notizen aus der JSON-Datei."""
    if NOTIZEN_DATEI.exists():
        with open(NOTIZEN_DATEI, "r", encoding="utf-8") as datei:
            return json.load(datei)
    return []


def notizen_speichern(notizen):
    """Speichert Notizen in der JSON-Datei."""
    with open(NOTIZEN_DATEI, "w", encoding="utf-8") as datei:
        json.dump(notizen, datei, indent=2, ensure_ascii=False)


def notiz_hinzufuegen(text):
    """Fuegt eine neue Notiz hinzu."""
    notizen = notizen_laden()
    neue_notiz = {
        "text": text,
        "erstellt": datetime.now().strftime("%Y-%m-%d %H:%M"),
        "erledigt": False
    }
    notizen.append(neue_notiz)
    notizen_speichern(notizen)
    print(f"Notiz hinzugefuegt: {text}")


def notizen_anzeigen():
    """Zeigt alle Notizen an."""
    notizen = notizen_laden()
    if not notizen:
        print("Keine Notizen vorhanden.")
        return
    for i, notiz in enumerate(notizen, 1):
        status = "x" if notiz["erledigt"] else " "
        print(f"  [{status}] {i}. {notiz['text']} ({notiz['erstellt']})")


# Ausprobieren
notiz_hinzufuegen("Python-Tutorial durcharbeiten")
notiz_hinzufuegen("Einkaufen gehen")
notizen_anzeigen()

Praxis: Config-Datei lesen

import json
from pathlib import Path

STANDARD_CONFIG = {
    "app_name": "MeineApp",
    "version": "1.0",
    "debug": False,
    "max_eintraege": 100,
    "farben": {
        "hintergrund": "#FFFFFF",
        "text": "#333333"
    }
}

def config_laden(pfad="config.json"):
    """Laedt die Konfiguration oder erstellt eine Standardkonfiguration."""
    config_pfad = Path(pfad)
    if config_pfad.exists():
        with open(config_pfad, "r", encoding="utf-8") as datei:
            return json.load(datei)
    else:
        print("Keine Config gefunden -- erstelle Standardkonfiguration...")
        with open(config_pfad, "w", encoding="utf-8") as datei:
            json.dump(STANDARD_CONFIG, datei, indent=4, ensure_ascii=False)
        return STANDARD_CONFIG.copy()


config = config_laden()
print(f"App: {config['app_name']} v{config['version']}")
print(f"Debug-Modus: {config['debug']}")

Uebungen

Uebung 1: Einkaufsliste

Schreibe ein Programm, das eine Einkaufsliste in einer Textdatei verwaltet. Es soll Artikel hinzufuegen, alle anzeigen und die Liste loeschen koennen.

def artikel_hinzufuegen(artikel):
    with open("einkaufsliste.txt", "a", encoding="utf-8") as datei:
        datei.write(artikel + "\n")
    print(f"'{artikel}' hinzugefuegt!")

def liste_anzeigen():
    try:
        with open("einkaufsliste.txt", "r", encoding="utf-8") as datei:
            zeilen = datei.readlines()
            if not zeilen:
                print("Die Liste ist leer.")
                return
            print("--- Einkaufsliste ---")
            for i, zeile in enumerate(zeilen, 1):
                print(f"  {i}. {zeile.strip()}")
    except FileNotFoundError:
        print("Noch keine Liste vorhanden.")

def liste_loeschen():
    with open("einkaufsliste.txt", "w", encoding="utf-8") as datei:
        pass  # Leere Datei
    print("Liste geloescht!")

# Test
artikel_hinzufuegen("Milch")
artikel_hinzufuegen("Brot")
artikel_hinzufuegen("Kaese")
liste_anzeigen()

Uebung 2: Woerterzaehler

Lies eine Textdatei ein und zaehle, wie oft jedes Wort vorkommt:

from collections import Counter

def woerter_zaehlen(dateipfad):
    with open(dateipfad, "r", encoding="utf-8") as datei:
        text = datei.read().lower()
        woerter = text.split()
        zaehler = Counter(woerter)

        print("Die 10 haeufigsten Woerter:")
        for wort, anzahl in zaehler.most_common(10):
            print(f"  {wort}: {anzahl}x")

# woerter_zaehlen("mein_text.txt")

Uebung 3: Kontaktbuch als JSON

Erstelle ein Kontaktbuch, das Namen, Telefonnummern und E-Mail-Adressen in einer JSON-Datei speichert:

import json
from pathlib import Path

KONTAKTE_DATEI = Path("kontakte.json")

def kontakte_laden():
    if KONTAKTE_DATEI.exists():
        return json.loads(KONTAKTE_DATEI.read_text(encoding="utf-8"))
    return {}

def kontakt_speichern(name, telefon, email):
    kontakte = kontakte_laden()
    kontakte[name] = {"telefon": telefon, "email": email}
    KONTAKTE_DATEI.write_text(
        json.dumps(kontakte, indent=2, ensure_ascii=False),
        encoding="utf-8"
    )
    print(f"Kontakt '{name}' gespeichert!")

def kontakt_suchen(name):
    kontakte = kontakte_laden()
    if name in kontakte:
        k = kontakte[name]
        print(f"{name}: {k['telefon']} | {k['email']}")
    else:
        print(f"Kontakt '{name}' nicht gefunden.")

# Test
kontakt_speichern("Anna", "0170-1234567", "anna@example.com")
kontakt_speichern("Ben", "0171-9876543", "ben@example.com")
kontakt_suchen("Anna")

Pro-Tipp: Fehlerbehandlung bei Dateioperationen

Dateien koennen fehlen, Berechtigungen koennen falsch sein, die Festplatte kann voll sein. Verwende immer Try-Except bei Dateioperationen in echten Programmen:

from pathlib import Path

def sichere_datei_lesen(pfad):
    try:
        with open(pfad, "r", encoding="utf-8") as datei:
            return datei.read()
    except FileNotFoundError:
        print(f"Datei '{pfad}' nicht gefunden!")
        return None
    except PermissionError:
        print(f"Keine Berechtigung fuer '{pfad}'!")
        return None
    except UnicodeDecodeError:
        print(f"Datei '{pfad}' hat ein unbekanntes Encoding!")
        return None

Und noch ein goldener Tipp: Nutze pathlib.Path.exists(), um vorher zu pruefen, ob eine Datei existiert — aber verlasse dich nicht allein darauf, denn zwischen Pruefung und Zugriff kann sich der Zustand aendern (Race Condition). Die Kombination aus Pruefung und Try-Except ist die sicherste Variante.

Zurück zum Python Kurs