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.

Easy Python 3.9+ Aug 9, 2026 OOP & classes 12 views 0 copies

Python code

23 lines
Python 3.9+
class 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

stdout
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

  1. Use `@contextmanager` decorator from `contextlib` to define generator-based context manager.
  2. 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

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from OOP & classes

Related tutorials and quizzes for this topic.