Python context managers are the language’s answer to the question “how do I guarantee cleanup even when an exception occurs?” The with statement calls __enter__ on entry and __exit__ on exit — even if an exception is raised. This makes resource management both safe and readable.
⚡ TL;DR: with statement calls __enter__ on entry, __exit__ on exit (even on exception). Implement via __enter__/__exit__ methods or @contextmanager decorator. Use contextlib.suppress to ignore specific exceptions. ExitStack for dynamic context managers. Multiple managers in one with statement.
__enter__ and __exit__ — Python context managers
class DatabaseConnection:
def __init__(self, dsn): self.dsn = dsn
def __enter__(self):
self.conn = create_connection(self.dsn)
return self.conn # Value bound to 'as' variable
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type: # Exception occurred
self.conn.rollback()
else:
self.conn.commit()
self.conn.close()
return False # False = don't suppress exception
# Return True to suppress the exception
with DatabaseConnection('postgresql://...') as conn:
conn.execute('INSERT INTO ...')
# Auto-commits or rolls back, always closes@contextmanager — the easy way
from contextlib import contextmanager
import time
@contextmanager
def timer(name=''):
start = time.perf_counter()
try:
yield # Code inside 'with' block runs here
finally: # Runs even on exception
elapsed = (time.perf_counter()-start)*1000
print(f'{name}: {elapsed:.1f}ms')
with timer('database query'):
results = db.execute('SELECT ...') # Timed!
# Transaction context manager:
@contextmanager
def transaction(db):
try:
yield db
db.commit()
except:
db.rollback()
raise # Re-raise after rollbackMultiple and nested managers
# Multiple managers in one with:
with open('input.txt') as f_in, open('output.txt','w') as f_out:
f_out.write(f_in.read())
# Both files closed even if exception!
# contextlib.suppress — ignore specific exceptions:
from contextlib import suppress
with suppress(FileNotFoundError):
os.remove('/tmp/temp_file') # OK if file doesn't exist
# Same as: try/except FileNotFoundError: pass (but cleaner)contextlib.ExitStack — dynamic managers
from contextlib import ExitStack
# Open variable number of files:
file_names = ['a.txt','b.txt','c.txt']
with ExitStack() as stack:
files = [stack.enter_context(open(f)) for f in file_names]
# All files open, all will be closed on exit
data = [f.read() for f in files]
# ExitStack.callback: register any cleanup function
with ExitStack() as stack:
conn = db.connect()
stack.callback(conn.close) # Always closes
stack.callback(conn.rollback) # Always rolls back (if not committed)- ✅ @contextmanager for simple context managers (no class needed)
- ✅ Multiple managers in one with statement
- ✅ contextlib.suppress instead of empty except blocks
- ✅ ExitStack for dynamic or variable numbers of managers
- ❌ Never return True from __exit__ unless you intentionally suppress exceptions
- ❌ Never put cleanup in finally when with handles it
External reference: Python contextlib documentation.
Recommended Reading
→ Designing Data-Intensive Applications — The bible of distributed systems and production engineering at scale.
→ The Pragmatic Programmer — Timeless engineering wisdom every senior developer needs.
Affiliate links. We earn a small commission at no extra cost to you.
Free Weekly Newsletter
🚀 Join 2,000+ Senior Developers
Get expert-level JavaScript, Python, AWS, system design and AI secrets every week. Zero fluff, pure signal.
Related: Python Decorators Explained: From Simple Wrappers to Production Patterns · Python asyncio vs Threading vs Multiprocessing: When to Use Each · Python Dictionary Methods and Tricks: The Complete Guide
Related: Node.js Error Handling: From try/catch to Production Error Monitoring · Python Dictionary Methods and Tricks: The Complete Guide for 2025 · Day 64: Secret-Aware Context Filters
Watch: 100 Days of AI on YouTube
Short videos from CheatCoders, one AI engineering topic per day.
Most viewed
- Python Decorators Explained: From Simple Wrappers to Production Patterns
- Claude Code vs Cursor vs GitHub Copilot: Choose by Workflow, and Set Up One Repo That Works With All Three
- AI Agent Frameworks in 2025: LangGraph vs CrewAI vs AutoGen vs Raw API
- Python String Methods: Every str Method With Real Production Examples
- API Debugging in 30 Seconds: The Fastest Ways to Fix API Issues
Newly added
- n8n vs AI Agent: I Gave Both the Same Job (Local, Ollama)
- Local AI Video Generator: Build Your Own App (Free, Python, No GPU)
- AI Wrote Raw Binary Instead of Code. Here’s What Happened (WebAssembly)
- I Built a Browser That Only Runs Encrypted Binary (Ep 1)
- RAG From Scratch: Chunking, Embeddings, Reranking and Evaluation (Real Numbers)
Deep-dive PDF
Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.
Already subscribed? or open the subscribe page.
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.
