The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Manage one resourcewith open(path, encoding='utf-8') as file: data = file.read()View examples
Manage several resourceswith open(source) as src, open(target, 'w') as dst: copy(src, dst)View examples
Return an acquired resourcedef __enter__(self): return self.resourceView examples
Handle exitdef __exit__(self, exc_type, exc, traceback): self.close()View examples
Create from a generator@contextmanagerView examples
Close an objectwith closing(resource) as value: use(value)View examples
Suppress selected errorswith suppress(FileNotFoundError): path.unlink()View examples
Redirect standard outputwith redirect_stdout(buffer): print('captured')View examples
Manage dynamic contextswith ExitStack() as stack: files = [stack.enter_context(open(p)) for p in paths]View examples
Register cleanupstack.callback(cleanup, resource)View examples
Use optional contextmanager = open(path) if path else nullcontext(sys.stdout)View examples

A context manager brackets a controlled region with setup and guaranteed exit behavior. Prefer with over duplicated try/finally cleanup, keep exception suppression narrow and explicit, and use ExitStack when the number of managed resources is decided at runtime.

Step by step

Detailed examples

01

Make ownership and lifetime visible

with evaluates and enters managers before the suite and invokes exit even on return or exception. Multiple managers exit in reverse order. Do not return a resource owned by a completed with block unless its API explicitly remains usable afterward.

Read and automatically close
from io import StringIO

with StringIO('alpha\nbeta') as file:
    print(file.readline().strip())
    print(file.closed)
print(file.closed)
Output
alpha
False
True
Back to quick reference ↑
02

Implement the protocol when state belongs on an object

__enter__ returns the bound value. __exit__ receives exception details and always runs after a successful enter. Returning a truthy value suppresses the exception, so normally return False or None; cleanup failures should not silently replace useful context.

Trace a managed region
class Traced:
    def __enter__(self):
        print('enter')
        return self
    def __exit__(self, exc_type, exc, traceback):
        print('exit', exc_type.__name__ if exc_type else 'clean')
        return False

with Traced():
    print('work')
Output
enter
work
exit clean
Back to quick reference ↑
03

Use one yield between setup and cleanup

@contextmanager turns a generator factory into a context manager. Code before yield performs setup, the yielded value is bound by as, and finally performs cleanup. The generator must yield exactly once; catch exceptions only when the manager can genuinely handle or translate them.

Temporary dictionary state
from contextlib import contextmanager

@contextmanager
def temporary(mapping, key, value):
    old = mapping.get(key)
    mapping[key] = value
    try:
        yield mapping
    finally:
        if old is None: mapping.pop(key, None)
        else: mapping[key] = old

settings = {}
with temporary(settings, 'mode', 'test'): print(settings)
print(settings)
Output
{'mode': 'test'}
{}
Back to quick reference ↑
04

Use focused standard adapters

closing adapts an object with close but no context protocol. suppress should cover only the expected statement because it can conceal programming errors of the same type. redirect_stdout changes global process state and is unsuitable for concurrent library isolation. nullcontext unifies optional ownership paths.

Suppress one expected absence
from contextlib import nullcontext, suppress

values = {'ready': True}
with suppress(KeyError):
    del values['missing']
with nullcontext(values) as current:
    print(current)
Output
{'ready': True}
Back to quick reference ↑
05

Stack a runtime-selected set of resources

ExitStack enters contexts and registers callbacks, then unwinds them last-in-first-out. If acquisition fails partway through, resources already registered are cleaned up. pop_all transfers callbacks to another stack when ownership must outlive the current block.

Dynamic in-memory resources
from contextlib import ExitStack
from io import StringIO

with ExitStack() as stack:
    files = [stack.enter_context(StringIO(text)) for text in ['a', 'b']]
    stack.callback(print, 'cleanup callback')
    print([file.read() for file in files])
Output
['a', 'b']
cleanup callback
Back to quick reference ↑

Local code tester

Build a context manager

Edit setup, yielded state, and guaranteed cleanup behavior.

Runs in your browser
Output
Press Run to load Python locally.

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. Python Software Foundationcontextlib — Utilities for with-statement contextsdocs.python.org
  2. Python Software FoundationThe with statementdocs.python.org
  3. Python Software FoundationContext Manager Typesdocs.python.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback