contextlib Module: @contextmanager Generator Helper
1Concept
`contextlib.contextmanager` transforms a generator function into a context manager. Code before the `yield` statement acts as `__enter__()`; the value yielded is bound to the `as` target; code inside the `finally` block acts as `__exit__()`.
2Architecture Diagram
def manager(): setup() try: yield resource finally: cleanup() ---> Guarantees teardown!
3Code Example
Python 3.12
from contextlib import contextmanager
import time
@contextmanager
def execution_timer(label: str):
start = time.perf_counter()
try:
yield
finally:
duration = time.perf_counter() - start
print(f"[{label}] Finished in {duration:.6f}s")
with execution_timer("Data Ingestion Pipeline"):
total = sum(i for i in range(500_000))
print(f"Calculated sum: {total}")4Expected Output
[Data Ingestion Pipeline] Finished in 0.015214s Calculated sum: 124999750000
5Key Takeaways
- ✓Always wrap the `yield` statement inside a `try...finally` block to guarantee cleanup on exceptions.
- ✓Eliminates class boilerplate when creating simple resource wrappers.
- ✓If an exception occurs in the with block, it is re-raised at the `yield` point in the generator.