How do context managers and the with statement work in Python?
· Category: Python Programming
Short answer
A context manager ensures that setup and teardown code runs around a block, even if exceptions occur. The with statement is the standard way to use them. Implement __enter__ and __exit__ in a class, or use contextlib.contextmanager with a generator.
Steps
- Define
__enter__to return the resource. - Define
__exit__to clean up, accepting exception info. - Use
with MyContext() as resource:.
class ManagedFile:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
with ManagedFile("test.txt", "w") as f:
f.write("Hello")
Tips
contextlib.contextmanageris a simpler way to write context managers usingyield.contextlib.closingensures.close()is called on objects that have it but are not context managers.- Multiple context managers can be nested in a single
withline.
from contextlib import contextmanager
@contextmanager
def managed_list():
data = []
try:
yield data
finally:
print(f"Final list length: {len(data)}")
with managed_list() as lst:
lst.append(1)
lst.append(2)
Common issues
- If
__enter__raises an exception,__exit__is not called. __exit__receives exception info; returningTruesuppresses the exception, which is usually undesirable unless intended.- Forgetting to yield exactly once in a
contextmanagergenerator breaks the protocol.