Context managers guarantee setup and teardown via with—files, locks, and DB connections. Implement with __enter__/__exit__ or the @contextmanager decorator from contextlib.
with statement
with open("data.txt") as f:
data = f.read()
# file closed here
Custom context manager
from contextlib import contextmanager
@contextmanager
def tag(name):
print(f"[{name}] start")
try:
yield name
finally:
print(f"[{name}] end")
Important interview questions and answers
- Q: __exit__ and exceptions?
A: Receives exception info; return True to suppress; otherwise exception propagates after cleanup. - Q: contextmanager vs class?
A: Decorator suits simple setup/yield/teardown; class fits reusable stateful managers.
Self-check
- What keyword uses a context manager?
- When is __exit__ called?
Tip: with open(...) is the classic pattern—context managers guarantee cleanup.
Interview prep
- __exit__ return True?
Suppresses the exception—use sparingly; usually let exceptions propagate after cleanup.
- @contextmanager?
Generator-based manager—code before yield is __enter__, finally after yield is cleanup.