20.Context Managers & with
Context managers are a powerful feature in Python that help manage resources efficiently. They are commonly used for tasks such as opening files, acquiring locks, or connecting to databases, where setup and cleanup actions are required.
Syntax and Explanation
The most common way to use a context manager is with the ‘with’ statement. It ensures that resources are properly cleaned up after use, even if errors occur.
Example:
with open(‘example.txt’, ‘r’) as file:
data = file.read()
# file is automatically closed after the block
Creating a Custom Context Manager
You can create your own context manager using a class that implements __enter__ and __exit__ methods.
class MyContext:
def __enter__(self):
print(‘Entering context’)
return self
def __exit__(self, exc_type, exc_value, traceback):
print(‘Exiting context’)
with MyContext() as ctx:
print(‘Inside context’)
Using contextlib
The contextlib module provides utilities for creating context managers using generator functions.
from contextlib import contextmanager
@contextmanager
def managed_resource():
print(‘Setup’)
yield
print(‘Cleanup’)
with managed_resource():
print(‘Using resource’)
Use Cases
– File handling
– Database connections
– Thread locks
– Network connections
– Temporary changes to system state
Comparison with try-finally
Using try-finally blocks for resource management can be verbose and error-prone. Context managers simplify this by encapsulating setup and teardown logic.
# Using try-finally
file = open(‘example.txt’, ‘r’)
try:
data = file.read()
finally:
file.close()
# Using with
with open(‘example.txt’, ‘r’) as file:
data = file.read()
Best Practices
– Always use ‘with’ for resource management
– Prefer contextlib for simple context managers
– Ensure __exit__ handles exceptions gracefully
– Avoid manual resource cleanup when context managers are available