Introduction
The contextlib module provides utilities for working with context managers. It includes decorators like @contextmanager and @closing that simplify creating and using context managers.
@contextmanager Decorator
from contextlib import contextmanager
@contextmanager
def managed_resource():
resource = acquire_resource()
try:
yield resource
finally:
release_resource(resource)
with managed_resource() as r:
r.use()
@closing Decorator
from contextmanager import closing
from urllib.request import urlopen
with closing(urlopen("http://example.com")) as page:
content = page.read()
Nested Context Managers
from contextlib import ExitStack
with ExitStack() as stack:
file1 = stack.enter_context(open("file1.txt"))
file2 = stack.enter_context(open("file2.txt"))
Context Manager for Timing
import time
from contextlib import contextmanager
@contextmanager
def timer(name):
start = time.time()
yield
print(f"{name} took {time.time() - start:.2f}s")
with timer("operation"):
perform_operation()
Practice Problems
- Create a context manager for database connections
- Implement a timing context manager
- Use @closing with a network resource
- Create nested context managers
- Implement a retry context manager