← Back to articles

Conext manager in python

· 2 min read

Conext manager in python

Yes, the with keyword in Python is used to invoke a context manager. A context manager is an object designed to handle resource allocation and cleanup automatically, effectively wrapping your code block in a safe, automated try...finally layout.

The classic example is opening a file. Instead of manually closing the file, the with statement ensures the file closes the moment the code inside the block finishes executing—even if an error occurs.

How It Works Behind the Scenes

For any object to work with the with keyword, it must follow the Context Manager Protocol. This means it implements two special "dunder" methods

1 . __enter__(): This method runs before the code block inside the with statement starts. Whatever it returns is assigned to the variable defined after the as keyword.

__exit__(): This method runs after the code block terminates or is interrupted by an exception. This is where your cleanup code (like closing a database connection or releasing a thread lock) lives.

Two Ways to Create Custom Context Managers

1.The Class-Based Approach (Explicit Protocol)

You can build a context manager by defining a class that explicitly provides the enter and exit magic methods:

class ManagedDatabase:
    def __enter__(self):
        print("Connecting to the database...")
        self.connection = "Active Connection"
        return self.connection  # Bound to the 'as' variable

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Closing the database connection safely.")
        # If an error happened inside the block, details are sent to exc_type, exc_val, and exc_tb
        # Returning True here would suppress an internal exception if needed

Usage:
with ManagedDatabase() as db:
    print(f"Performing operations using: {db}")

 Output:
 Connecting to the database...
 Performing operations using: Active Connection
 Closing the database connection safely.

2.The Generator-Based Approach (Simpler Syntax)

If writing an entire class feels like overkill, Python's standard library provides a helpful utility in the contextlib module. You can decorate a generator function using @contextmanager

from contextlib import contextmanager

@contextmanager
def open_file_context(filename, mode):
    print("Opening file...")
    file_obj = open(filename, mode)
    try:
        yield file_obj  # Hands over control to the code inside the 'with' block
    finally:
        print("Closing file...")
        file_obj.close()  # Guarantees cleanup happens

 Usage:

with open_file_context("example.txt", "w") as f:
    f.write("Hello, World!")

Everything before the yield statement acts as the __enter__ block, while everything inside the finally block acts as the __exit__ logic.

Would you like to build a custom context manager for a specific use case, such as timing how long code takes to run or managing an external API connection?