🧠 Python Context Managers β€” The Power of with Statement

Introduction 🌟

A Context Manager in Python is a special tool that helps you manage resources (like files, database connections, network sockets, locks) efficiently. The with statement ensures that resources are properly cleaned up β€” even if an error occurs.

Note

πŸ’‘ Think of a context manager as:
β€œDo something before a block runs, and clean up afterward.”

1. Basic Example of with Statement πŸ“„

with_file.py

with open("data.txt", "r") as file:
    content = file.read()
    print(content)

βœ” File is automatically closed after block
βœ” No need to call file.close()

2. How Context Managers Work Internally 🧩

Any object that works with with must implement two methods:

  • __enter__() β†’ runs before block
  • __exit__() β†’ runs after block (even if errors occur)

3. Creating Your Own Context Manager (Class-Based) πŸ—οΈ

class_context_manager.py

class MyContext:
    def __enter__(self):
        print("Entering context...")
        return "Resource Ready"

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Exiting context...")
        print("Cleaning up resources")
        return False  # Do NOT suppress exceptions

with MyContext() as resource:
    print(resource)

βœ” __enter__ returns the object used inside with
βœ” __exit__ is guaranteed to run

4. Handling Exceptions Inside Context Managers ⚠️

context_exception.py

class Demo:
    def __enter__(self):
        print("Start")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("End")
        return True  # suppress exceptions

with Demo():
    raise ValueError("Something went wrong!")

βœ” Returning True from __exit__() prevents the exception from propagating.

5. Creating a Context Manager Using contextlib (Decorator Style) πŸŽ€

This is easier and more readable than writing a class.

contextlib_manager.py

from contextlib import contextmanager

@contextmanager
def my_manager():
    print("Before block")
    yield "Hello"
    print("After block")

with my_manager() as msg:
    print(msg)

βœ” yield splits the setup and teardown logic.

6. Real-World Example: Opening Files πŸ“‚

file_manager.py

with open("log.txt", "a") as log:
    log.write("New activity added\n")

βœ” Automatically closes file
βœ” Prevents memory leaks

7. Real-World Example: Database Connection πŸ”Œ

db_manager.py

class DB:
    def __enter__(self):
        print("Connecting to DB...")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Closing DB connection...")

with DB():
    print("Querying DB...")

8. Real-World Example: Timer Context Manager ⏳

timer_context.py

import time

class Timer:
    def __enter__(self):
        self.start = time.time()
        return self

    def __exit__(self, *args):
        print("Elapsed:", time.time() - self.start)

with Timer():
    for _ in range(1000000):
        pass

9. Real-World Example: Temporary Directory (contextlib) πŸ“

temp_dir.py

from contextlib import TemporaryDirectory

with TemporaryDirectory() as temp_dir:
    print("Temp folder created:", temp_dir)
    # folder auto-deletes after block

10. Nested Context Managers πŸ”—

nested_contexts.py

with open("a.txt") as f1, open("b.txt") as f2:
    print(f1.read(), f2.read())

βœ” Clean & readable syntax.

11. Using Context Managers in Classes 🎯

class_usage.py

class Writer:
    def __init__(self, filename):
        self.filename = filename

    def __enter__(self):
        self.file = open(self.filename, "w")
        return self.file

    def __exit__(self, *args):
        self.file.close()

with Writer("msg.txt") as f:
    f.write("Hello!")

12. Best Practices πŸ’‘

  • βœ” Always use with open() for file handling
  • βœ” Use contextlib for simple custom managers
  • βœ” Do not suppress exceptions unless necessary
  • βœ” Keep setup in __enter__ and cleanup in __exit__
  • βœ” Use context managers for any resource cleanup

Conclusion πŸŽ‰

>>β€œContext Managers make your code safer, cleaner, and more reliable by ensuring resources are always properly handled.” ✨

You now fully understand Context Managers & the with Statement in Python! Want the next topic? Try JSON Handling, CSV Files, OOP (Classes), or Exception Hierarchy. Just tell me! 😊