How do you write your own context manager in Python?
Either write a class with __enter__ and __exit__ methods, or write a generator function decorated with @contextlib.contextmanager that yields once. Code before the yield is setup and code after it is cleanup, which should sit in a finally block.
Explain it simply
Think of a hotel room: on entry you get the key and the lights come on (setup), and on checkout the room is cleaned and the key returned (cleanup), whether the stay went well or not. A context manager is that agreement around a block of code.
Example
from contextlib import contextmanager
import time
class Timer:
def __enter__(self):
self.start = time.perf_counter()
return self
def __exit__(self, exc_type, exc, tb):
self.elapsed = time.perf_counter() - self.start
return False # do not hide exceptions
with Timer() as t:
total = sum(range(1000))
print(total) # Output: 499500
print(t.elapsed >= 0) # Output: True
@contextmanager
def announce(name):
print("start", name)
try:
yield name.upper()
finally:
print("end", name)
with announce("job") as label:
print(label)
# Output: start job
# Output: JOB
# Output: end jobWhat to say in the interview
"A class-based manager implements __enter__ and __exit__; __exit__ receives exception details and returns True only if it wants to suppress the exception. The contextlib.contextmanager decorator does the same with a generator: setup, yield, then cleanup in finally. I use it for locks, temporary state, timers and resource handling."