with statement. Once you see how they work, you will use them everywhere.
What a Context Manager Does
A context manager wraps a block of code with two operations:- Setup — runs before your block executes (open the file, acquire the lock, start a timer)
- Teardown — runs after your block finishes, regardless of whether an exception was raised
try / finally block every time — more lines, more chances to forget the cleanup.
How with Works: __enter__ and __exit__
Any object that implements __enter__ and __exit__ can be used with with. Python calls them automatically:
__enter__ is bound to the variable after as.
Writing Your Own Context Manager: Class-Based
If you return
True from __exit__, Python suppresses any exception that was raised inside the with block. Return False (or None) to let exceptions propagate normally.Writing Your Own Context Manager: Generator-Based
For most use cases, the@contextmanager decorator from contextlib is simpler than writing a full class. You write a generator function, yield the value, and Python handles the rest.
finally block runs even when an exception is raised inside the with block, giving you the same guarantee as __exit__.
Exception Handling Inside the Generator
When an exception escapes thewith block, Python injects it back into the generator at the suspended yield using generator.throw(). You can catch it inside the generator:
Built-In Context Managers
File I/O
open() returns a context manager that closes the file handle on exit — even if an exception occurs mid-read.Thread Locks
threading.Lock() acquires the lock on enter and releases it on exit, preventing deadlocks.Temporary Directory
tempfile.TemporaryDirectory() creates a temp dir and deletes it (with all contents) when the block exits.Decimal precision
decimal.localcontext() temporarily changes arithmetic precision within a block without affecting global settings.Timing Code with a Context Manager
A context manager makes a clean, reusable timer:How FastAPI Uses the Same Pattern
FastAPI’sDepends() system lets you use generator-based context managers as dependencies. FastAPI calls next() to run the setup, injects the yielded value into your endpoint, and then resumes the generator after the endpoint returns — guaranteeing cleanup before the HTTP response is sent.
yield + finally pattern you write with @contextmanager — FastAPI just automates the wiring.
When to Reach for a Context Manager
1
Any resource that must be released
Files, database connections, network sockets, thread locks, GPU memory — anything that needs cleanup belongs in a context manager.
2
Wrapping setup/teardown around a block
Starting a transaction, entering a profiler, redirecting stdout — anything with a matching before/after pair.
3
Suppressing or logging specific exceptions
contextlib.suppress(FileNotFoundError) is a one-liner context manager that silently ignores specific exceptions.