A context manager is an object designed for with statements. It sets something up on entry and reliably tears it down on exit, even if an exception occurs.
Classic examples: files, locks, DB sessions, temporary monkeypatches, timing blocks.
# Built-in file context manager
with open("data.txt") as f:
text = f.read()
# file closed automatically here
from contextlib import contextmanager
import time
@contextmanager
def timed(label):
start = time.perf_counter()
try:
yield
finally:
print(f"{label}: {time.perf_counter() - start:.4f}s")
with timed("work"):
sum(range(100000))You can implement the protocol with __enter__ / __exit__ on a class, or use contextlib.contextmanager on a generator.
Why interviewers care: Resource leaks (unclosed files/connections) are common bugs; with is the idiomatic fix.