What they are
Context managers ensure that setup and cleanup code runs automatically. The with statement is the most common way to use them.
File handling
The most common use—automatically closes files:
# Without context manager (must remember to close):
file = open('data.txt', 'r')
content = file.read()
file.close() # Easy to forget!
# With context manager (auto-closes):
with open('data.txt', 'r') as file:
content = file.read()
# File automatically closed here, even if error occurs
Creating your own
Use a class with __enter__ and __exit__ methods:
class Timer:
def __enter__(self):
import time
self.start = time.time()
return self
def __exit__(self, *args):
import time
print(f"Took {time.time() - self.start:.2f} seconds")
# Use it:
with Timer():
# Do something
time.sleep(1)
Using contextlib
For simpler cases, use contextlib.contextmanager:
from contextlib import contextmanager
@contextmanager
def timer():
import time
start = time.time()
yield
print(f"Took {time.time() - start:.2f} seconds")
with timer():
time.sleep(1)
Why use context managers
- Automatic cleanup (files, connections, locks)
- Error-safe (cleanup happens even if error occurs)
- Cleaner code (no manual cleanup needed)
- Resource management (prevents leaks)