All concepts

Context Managers

with-blocks acquire and always release a resource—cleanup guaranteed, even on error.

Python · Intermediate · ~5 min

In plain English

A block that guarantees cleanup. Whatever happens inside — success, exception, early return — the file gets closed and the lock gets released.

Why it's worth your time

It's how you stop leaking connections, file handles and locks, which is the most common source of mysterious production exhaustion.

If you remember three things

  • with handles setup and teardown as a pair
  • __exit__ runs even on exception
  • @contextmanager turns a generator into one

Overview

A context manager pairs setup and teardown around a block via the with statement. __enter__ acquires a resource and returns a handle; __exit__ releases it when the block ends—and runs even if the block raises, so cleanup is guaranteed. contextlib.contextmanager lets you write one as a generator.

In an interview

A context manager guarantees a resource is cleaned up. with obj calls obj.__enter__ on the way in and obj.__exit__ on the way out—crucially, __exit__ runs even if the block raises, so files close, locks release, and transactions roll back no matter what. It's essentially a foolproof try/finally. The easiest way to write one is the @contextmanager decorator over a generator, where code before yield is setup and code after is teardown.

Production defaults

Always use with
for files, connections, locks, transactions and temp resources
Custom ones
@contextlib.contextmanager with try/finally around the yield
Async
async with and __aenter__/__aexit__ for async resources

What breaks

  • Connection pool exhausted in production — Something isn't being released on the error path. with makes that structurally impossible.
  • Cleanup skipped on exception — Your teardown is after the yield but not inside a finally. Wrap it.

Watch it explained

[Practice Problems] Python Context Managers - Visually Explained — Visually Explained, 7:05

Related