Python Context Manager with-Statement einfach erklärt
Context Manager und das with-Statement: So verwaltet Python Ressourcen wie Dateien automatisch – einfach erklärt für den Einstieg in die Praxis.
Von Marcel Schmidtpeter 23. Sept. 2026
Stell dir vor, dein Python-Skript schreibt Protokolldaten in eine Datei. Mitten im Schreibvorgang fliegt eine Exception - das Skript stürzt ab. Jetzt hast du ein Problem: Die Datei ist noch geöffnet, der Schreibpuffer wurde nie geleert, und im schlimmsten Fall fehlen Daten. Genau für solche Situationen gibt es in Python das with-Statement in Kombination mit einem Context Manager. Es sorgt dafür, dass Ressourcen wie Dateien, Datenbankverbindungen oder Locks zuverlässig wieder freigegeben werden - egal ob dein Code fehlschlägt oder nicht.
Was ist das with-Statement in Python?
Das with-Statement ist eine Sprachkonstruktion in Python, die einen Codeblock ausführt und dabei automatisch eine Ressource öffnet und danach wieder schließt. Der Context Manager ist das Objekt dahinter, das steuert, was beim Betreten und Verlassen des Blocks passiert. Du kennst das vermutlich schon vom Dateien-Handling - Details dazu findest du in unserem Artikel zu open() und with.
So sieht der klassische Anwendungsfall aus:
with open("log.txt", "w") as file:
file.write("Server gestartet")
# Die Datei ist hier automatisch geschlossenDer Clou: `close()` musst du nicht selbst aufrufen. Python erledigt das für dich - auch dann, wenn im Block eine Exception auftritt.
Merke: `with` garantiert, dass Aufräum-Code (z. B. `close()`) immer ausgeführt wird - selbst bei Fehlern. Das ist der ganze Sinn der Sache.
Warum reicht try/finally nicht aus - oder doch?
Früher - und in vielen älteren Tutorials - sah Ressourcen-Management so aus:
file = open("log.txt", "w")
try:
file.write("Server gestartet")
finally:
file.close()Das funktioniert, ist aber umständlich zu schreiben. Und in der Praxis passiert ohnehin etwas anderes: Viele lassen das try/finally komplett weg und rufen nur `open()` auf. Genau das passiert Azubis und Berufseinsteigern im stressigen Projektalltag regelmäßig - und dann wundern sich alle, warum der Server irgendwann "Too many open files" meldet.
`with` macht exakt dasselbe wie try/finally, nur kürzer und ohne dass du etwas vergessen kannst:
with open("log.txt", "w") as file:
file.write("Server gestartet")Beide Varianten sind sicher. Die `with`-Variante ist die von der offiziellen Python-Dokumentation empfohlene Standard-Schreibweise.
Wie funktioniert ein Context Manager mit __enter__ und __exit__?
Ein Context Manager ist jedes Objekt, das die zwei Methoden `__enter__` und `__exit__` implementiert. Das sind sogenannte Dunder-Methoden, weil sie doppelte Unterstriche haben - mehr dazu in unserem Artikel zu Dunder-Methoden in Python. Der Ablauf beim `with`-Statement sieht so aus:
Python ruft `__enter__()` auf - hier wird die Ressource geöffnet. Der Rückgabewert landet hinter dem `as`.
Der Codeblock wird ausgeführt.
Python ruft immer `__exit__()` auf - hier wird aufgeräumt. Immer, auch bei Exceptions.
Kernidee: `__exit__` läuft garantiert - egal ob der Block normal endet oder mit einer Exception abbricht.
Du kannst dir das wie ein Hotelzimmer vorstellen: Beim Einchecken (`__enter__`) bekommst du den Schlüssel, beim Auschecken (`__exit__`) wird das Zimmer aufgeräumt - egal ob du es benutzt hast oder nicht.
Wie schreibst du einen eigenen Context Manager als Klasse?
Eine eigene Klasse wird zum Context Manager, sobald sie `__enter__` und `__exit__` implementiert. Ein praktisches Beispiel - ein Timer für Performance-Messungen:
import time
class Timer:
def __enter__(self):
self.start = time.time()
return self # landet hinter "as"
def __exit__(self, exc_type, exc_value, traceback):
self.duration = time.time() - self.start
print(f"Dauer: {self.duration:.2f} Sekunden")
return False # Exceptions nicht unterdruecken
with Timer():
total = sum(range(10_000_000))Die drei Parameter von `__exit__` enthalten Infos zu einer eventuellen Exception. Wichtig: Gibt `__exit__` `True` zurück, schluckt Python die Exception komplett. Das führt uns direkt zu den typischen Fehlern.
Was macht der @contextmanager-Decorator aus der contextlib?
Mit `@contextmanager` aus der Standardbibliothek `contextlib` schreibst du einen Context Manager als Generator-Funktion statt als Klasse. Der Code vor dem `yield` entspricht `__enter__`, der Code danach `__exit__`:
from contextlib import contextmanager
@contextmanager
def open_database(url):
connection = connect(url) # steht fuer deine echte Connect-Funktion
try:
yield connection # hier laeuft der with-Block
finally:
connection.close()
with open_database("db://produktion") as conn:
conn.query("SELECT * FROM users")Das `try/finally` brauchst du hier, damit die Verbindung auch bei einer Exception geschlossen wird. Decorator-Syntax im Detail erklären wir im Artikel zu Python Decorators. Die vollständige Referenz findest du in der contextlib-Dokumentation.
Faustregel: Im `@contextmanager` gehört alles, was aufräumen soll, in einen `finally`-Block - nie einfach nur hinter das `yield`.
Welche Context Manager bringt Python mit?
Python liefert eine Reihe fertiger Context Manager mit, die du direkt nutzen kannst, ohne selbst etwas zu schreiben:
Context Manager | Modul | Wofür? |
`open()` | built-in | Dateien lesen/schreiben |
`threading.Lock()` | threading | Zugriffe synchronisieren |
`decimal.localcontext()` | decimal | Rechenregeln temporär ändern |
`redirect_stdout()` | contextlib | print-Ausgabe umleiten |
`TemporaryDirectory()` | tempfile | Temporäre Ordner anlegen und automatisch löschen |
Gerade `threading.Lock()` lohnt sich - warum Locks bei Nebenläufigkeit wichtig sind, erklären wir im Artikel zum GIL und Multithreading.
Welche Fehler passieren häufig bei with?
Die meisten Fehler rund um `with` fallen in drei Kategorien - hier die Klassiker.
Fehler 1: Die Datei nach dem with-Block weiter benutzen.
with open("daten.txt") as file:
lines = file.readlines()
print(file.read()) # ValueError: I/O operation on closed fileNach dem Block ist die Datei zu. Lies alles aus, was du brauchst, innerhalb des Blocks - oder speichere es in einer Variable wie `lines`.
Fehler 2: `return True` in `__exit__` - und Exceptions verschwinden.
def __exit__(self, exc_type, exc_value, traceback):
self.connection.close()
return True # SCHLECHT: unterdrueckt jede Exception!Damit schluckst du jeden Fehler im Block stillschweigend. Gib `False` zurück (oder gar nichts), damit Exceptions normal durchgereicht werden. Nur wenn du bewusst Fehler behandeln willst, darfst du `True` zurückgeben - und das ist selten.
Fehler 3: `yield` ohne `try/finally` im `@contextmanager`. Tritt im with-Block eine Exception auf, wird sie im Generator genau am `yield` geworfen. Ohne `try/finally` erreicht dein Aufräum-Code danach nie - die Ressource bleibt offen. Der `finally`-Block ist hier Pflicht, nicht Kür.
Übungstipp: Bau dir einen eigenen Context Manager
Nimm dir 15 Minuten und schreibe eine Klasse `IndentLogger`: Bei `__enter__` soll ein `"--> Block betreten"` ausgegeben werden, bei `__exit__` ein `"<-- Block verlassen"`. Erweitere sie dann so, dass sie mitzählt, wie oft sie verschachtelt genutzt wurde. So verstehst du sofort, dass `with`-Blöcke verschachtelbar sind. Fang klein an - auch wenn die Seite erstmal leer bleibt, hilft dir unser Tipp gegen die leere Seite bei Prüfungsangst.
FAQ: Häufige Fragen zu Python Context Manager with
Wann sollte ich with in Python verwenden?
Immer wenn du eine Ressource öffnest, die danach geschlossen oder freigegeben werden muss: Dateien, Datenbankverbindungen, Netzwerk-Sockets, Locks. Faustregel: Gibt es eine `close()`- oder `release()`-Methode, gehört das Objekt in ein `with`.
Was passiert bei einer Exception im with-Block?
`__exit__` wird trotzdem ausgeführt, danach wird die Exception normal weitergeworfen - sofern `__exit__` nicht `True` zurückgibt. Die Ressource wird also sicher freigegeben, dein Fehler geht aber nicht verloren. Wie du solche Fehler danach behandelst, zeigen wir im Artikel zu try except finally.
Kann ich mehrere Ressourcen in einem with-Statement öffnen?
Ja, mit Komma-getrennten Ausdrücken:
with open("quelle.txt") as src, open("ziel.txt", "w") as dst:
dst.write(src.read())Ab Python 3.10 darfst du Klammern setzen - praktisch, wenn die Zeile zu lang wird:
with (
open("quelle.txt") as src,
open("ziel.txt", "w") as dst,
):
dst.write(src.read())Was ist der Unterschied zwischen einer Context-Manager-Klasse und @contextmanager?
Die Klasse ist expliziter und besser, wenn du Zustand verwalten musst. Der Decorator ist kompakter und gut für einfache Fälle. Beide sind gleichwertig - `@contextmanager` ist letztlich nur eine bequeme Verpackung.
Ist with dasselbe wie ein finally-Block?
Funktional ja: Beide garantieren Aufräum-Code. `with` kombiniert das Öffnen der Ressource, die Zuweisung an eine Variable und das Aufräumen in einer einzigen, nicht vergessbaren Syntax.
Fazit
Der Python Context Manager zusammen mit dem with-Statement ist eine der elegantesten Lösungen in Python: Du deklarierst einmal, welche Ressource du brauchst, und Python garantiert dir die Freigabe. Ob Datei, Datenbank oder Lock - wer `with` konsequent nutzt, schreibt sichereren Code und vermeidet klassische Produktionsfehler wie offene File-Handles. Und wenn du irgendwann eigene Context Manager schreibst, verstehst du auch, was unter der Haube passiert: `__enter__`, `__exit__` - mehr ist es nicht.
Wenn du dich gerade auf eine Prüfung vorbereitest oder in deinem Informatik-Studium an Python-Themen hängst: Bei study-it.education findest du individuelle Nachhilfe für Fachinformatiker-Azubis, Studenten und Berufseinsteiger - auch zu genau diesem Thema. Schau vorbei, gemeinsam kommen wir dich weiter.
Brauchst du jemand, der das mit dir durchgeht?
Statt nochmal lesen: 30 min mit einem Senior-Dev.
Kostenloses Erstgespräch buchen →
Context Manager und das with-Statement: So verwaltet Python Ressourcen wie Dateien automatisch – einfach erklärt für den Einstieg in die Praxis.
marcel.schmidtpeter@study-it.education →Mehr Lesestoff
Python HTTP requests senden: GET, POST & mehr mit requests
So sendest du mit der Python-Bibliothek requests GET- und POST-Anfragen an APIs – mit Beispielen für Azubis, Studenten und Berufseinsteiger.
Python JSON verarbeiten mit dem -Modul – einfach erklärt
JSON in Python lesen und schreiben? Das -Modul macht's einfach – von .loads bis .dumps, hier lernst du alles Wichtige.
Python Datenbank verbinden: sqlite3 & SQLAlchemy einfach erklärt
Erfahre, wie du Python per sqlite3 oder SQLAlchemy mit Datenbanken verbindest – mit Praxisbeispielen für Azubis, Studenten & Berufseinsteiger.