How to Build a Context Manager Class in Python
Create a reusable context manager class that opens and automatically closes resources using the with statement.
Python code
23 linesclass FileResource:
def __init__(self, filename, mode='r'):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_value, traceback):
if self.file:
self.file.close()
return False
if __name__ == "__main__":
with FileResource("sample.txt", "w") as f:
f.write("Hello, resource management!")
with FileResource("sample.txt", "r") as f:
content = f.read()
print(content)
Output
Hello, resource management!
How it works
The __enter__ method opens the file and returns it, allowing the with statement to bind it to the as f target. The __exit__ method is called when the block exits, closing the file regardless of whether an exception occurred. Returning False from __exit__ ensures any exceptions propagate, so you can handle them outside. This pattern guarantees cleanup, preventing resource leaks. The class can be reused for different files by instantiating it each time.
Common mistakes
- Returning `True` from `__exit__` suppresses exceptions, which can hide bugs.
- Forgetting to initialize `self.file` to `None` in `__init__`, causing AttributeError if __enter__ raises.
- Assuming the same instance can be reused in multiple with statements; re-entrancy can break.
Variations
- Use `@contextmanager` decorator from `contextlib` to define generator-based context manager.
- Use `inspect` or `contextlib.ExitStack` for dynamically managing multiple resources.
Real-world use cases
- Managing database connections that must be committed or rolled back after each session.
- Acquiring and releasing file locks in concurrent applications to prevent data races.
- Wrapping network socket connections to ensure they close after data exchange.
Sponsored
More from OOP & classes
- Add property getter setter validation in Python easy
- Binary Tree Inorder Traversal in Python easy
- Borg pattern shared state in Python medium
- Bridge Pattern in Python: Separate Abstraction from Implementation medium
- Composable Predicates with the &, |, ~ Operators in Python medium
- Composition over Inheritance: How to Build a Wallet Account in Python easy
Keep learning
Related tutorials and quizzes for this topic.