AtomLearnAtomLearn
DashboardGoalsPathAchievementsReviewSign In
DashboardPython CoreContext Managers
Python CoreNot Started

Context Managers

with statements, __enter__/__exit__, and contextlib

0%
Knowledge0%
Learn & Drill
Fluency0%
Drill & Speed
Retention0%
Mastery & Review
Confidence0%
All modes
Practice

Free tier: read the explanation here. Upgrade to Pro for Drills, Speed challenges & Mastery badges.

Upgrade
Knowledge
Fluency
Retention

Knowledge Debt detected

You can study this freely — but your score may plateau if these foundations have gaps. The Mastery badge requires them to be solid.

Explanation

s guarantee that setup and teardown happen correctly — even when exceptions are raised.

The with statement:

python with open("file.txt") as f: data = f.read() # f.close() is guaranteed to be called here, even if an exception occurred

How it works — the :protocol[An informal interface — methods a class implements to support a behavior, like __enter__ and __exit__]:

python class ManagedFile: def __init__(self, path): self.path = path def __enter__(self): self.file = open(self.path) return self.file # bound to 'as' variable def __exit__(self, exc_type, exc_val, exc_tb): self.file.close() return False # False = don't suppress exceptions

contextlib.contextmanager — build one with a generator: ``python from contextlib import contextmanager @contextmanager def timer(): import time start = time.perf_counter() yield # code inside 'with' block runs here elapsed = time.perf_counter() - start print(f"Elapsed: {elapsed:.3f}s") with timer(): result = sum(range(1_000_000))

suppress — suppress specific exceptions cleanly: ``python from contextlib import suppress with suppress(FileNotFoundError): os.remove("temp.txt") # doesn't raise if file doesn't exist

Real-world uses: database transactions, locks (threading), temporary directories, mocking in tests, connection pools.

Examples

Database transaction context manager

The most common real-world pattern — guarantees atomicity

from contextlib import contextmanager

@contextmanager
def transaction(conn):
    try:
        yield conn
        conn.commit()
    except Exception:
        conn.rollback()
        raise

with transaction(db_conn) as conn:
    conn.execute("INSERT INTO users VALUES (?)", (name,))
    conn.execute("INSERT INTO audit_log VALUES (?)", (event,))
# commits if both succeed, rolls back if either raises

Temporary working directory

Combining multiple context managers and finally for guaranteed cleanup

import os
import tempfile
from contextlib import contextmanager

@contextmanager
def temp_directory():
    original = os.getcwd()
    with tempfile.TemporaryDirectory() as tmpdir:
        os.chdir(tmpdir)
        try:
            yield tmpdir
        finally:
            os.chdir(original)

with temp_directory() as d:
    # work here — directory is deleted on exit

How well did you understand this?

Next in Python Core

functools

Continue