0Pricing
Python Academy · Lesson

contextlib: @contextmanager

Create context managers concisely with the contextlib decorator.

contextlib: @contextmanager is a free Python Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Python Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why contextlib?

contextlib.contextmanager lets you write a context manager as a generator function instead of a class, reducing boilerplate.

from contextlib import contextmanager

@contextmanager
def managed():
    print("setup")
    yield
    print("teardown")

with managed():
    print("inside")

Yielding a Value

Whatever you yield is bound to the as variable in the with statement.

from contextlib import contextmanager

@contextmanager
def temp_list():
    lst = []
    yield lst
    print(f"Final list: {lst}")

with temp_list() as lst:
    lst.append(1)
    lst.append(2)

Exception Handling in @contextmanager

Wrap the yield in a try/finally to guarantee cleanup even if an exception occurs.

from contextlib import contextmanager

@contextmanager
def safe_open(path):
    f = open(path)
    try:
        yield f
    finally:
        f.close()

with safe_open("data.txt") as f:
    print(f.read())

Suppressing Exceptions

Catch the exception inside the generator to suppress it — same as returning True from __exit__.

from contextlib import contextmanager

@contextmanager
def ignore_value_errors():
    try:
        yield
    except ValueError:
        pass

with ignore_value_errors():
    raise ValueError("ignored")

contextlib.suppress

contextlib.suppress(*exceptions) is a ready-made context manager that suppresses specified exception types.

from contextlib import suppress

with suppress(FileNotFoundError):
    open("missing.txt")

print("continues")

contextlib.closing

closing(obj) creates a context manager that calls obj.close() on exit. Useful for objects that have close() but no __exit__.

from contextlib import closing
from urllib.request import urlopen

with closing(urlopen("https://example.com")) as page:
    content = page.read()

contextlib.nullcontext

nullcontext is a no-op context manager. Useful when a context manager is optional.

from contextlib import nullcontext

def process(data, lock=None):
    cm = lock if lock is not None else nullcontext()
    with cm:
        return [x*2 for x in data]

contextlib.ExitStack

ExitStack lets you manage a variable number of context managers dynamically.

from contextlib import ExitStack

files = ["a.txt", "b.txt", "c.txt"]
with ExitStack() as stack:
    handles = [stack.enter_context(open(f)) for f in files]
    data = [h.read() for h in handles]

Reusing a @contextmanager

A generator-based context manager is single-use per call. Call the decorated function again to reuse it.

from contextlib import contextmanager

@contextmanager
def counter():
    count = 0
    yield lambda: count.__add__  # each call is independent
    print("done")

with counter():
    pass
with counter():
    pass

asynccontextmanager

For async code, use contextlib.asynccontextmanager to write async with managers as generators.

from contextlib import asynccontextmanager

@asynccontextmanager
async def async_session():
    session = await create_session()
    try:
        yield session
    finally:
        await session.close()

contextlib.redirect_stdout

Redirect standard output to any file-like object temporarily.

import io
from contextlib import redirect_stdout

buf = io.StringIO()
with redirect_stdout(buf):
    print("captured")

print(buf.getvalue())  # captured

Quick Check

In a @contextmanager generator, where should cleanup code be placed to guarantee it runs even on exception?

Recap

@contextmanager turns a generator into a context manager. Use try/finally around yield for safe cleanup. The contextlib module also provides suppress, nullcontext, ExitStack, and more.

Frequently asked questions

Is the “contextlib: @contextmanager” lesson free?

Yes — the full text of “contextlib: @contextmanager” is free to read here on the web, and the Python Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Python Academy course, upgrade to CoddyKit PRO.

What will I learn in “contextlib: @contextmanager”?

Create context managers concisely with the contextlib decorator. You practise Python Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Python Academy?

No prior experience is required. Python Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “contextlib: @contextmanager” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Python Academy lesson?

Yes. Every Python Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. The with Statement in Depth
  2. __enter__ and __exit__ Protocol
  3. contextlib: @contextmanager
  4. Practical Context Manager Patterns
← Back to Python Academy