MiddleCodeCommonNot answered yet
Write a context manager for resource cleanup
Implement a context manager that acquires a resource, hands it to the with block, and always releases it.
Requirements:
- Print "acquire" on entry and "release" on exit.
- The release must run even if the body raises an exception.
from contextlib import contextmanager
@contextmanager
def open_resource(name):
# your code here
with open_resource("db") as r:
print(f"using {r}")
Write the implementation.
Use @contextlib.contextmanager: acquire before yield value (bound to as), and release in a finally so cleanup runs even on exception. It is equivalent to a class with __enter__ / __exit__. The with statement guarantees the code after yield (the finally) executes.
- ✗Omitting
try/finally, so cleanup is skipped when the body raises - ✗Using
returninstead ofyieldin a@contextmanager - ✗Releasing before the
yield, so the body runs after cleanup
- →How does
@contextmanagermap the code before/afteryieldto__enter__/__exit__? - →What can
__exit__do that a@contextmanagerfinallyblock cannot easily do?
Contents
Task
Implement a context manager via @contextmanager that acquires a resource, hands it to the block, and always releases it.
Solution
from contextlib import contextmanager
@contextmanager
def open_resource(name):
print(f"acquire {name}")
try:
yield name # value bound to 'as'
finally:
print(f"release {name}") # runs even on exception
with open_resource("db") as r:
print(f"using {r}")
Key points
- The code before
yieldis__enter__; the code infinallyafteryieldis__exit__. try/finallyguarantees release even when thewithbody raises.yield(notreturn) hands over the resource and suspends the generator until block exit.
Contents