Python Language Context Managers (“with” Statement) Writing your own context manager


A context manager is any object that implements two magic methods __enter__() and __exit__() (although it can implement other methods as well):

class AContextManager():

    def __enter__(self):
        # optionally return an object
        return "A-instance"

    def __exit__(self, exc_type, exc_value, traceback):
        print("Exited" + (" (with an exception)" if exc_type else ""))
        # return True if you want to suppress the exception

If the context exits with an exception, the information about that exception will be passed as a triple exc_type, exc_value, traceback (these are the same variables as returned by the sys.exc_info() function). If the context exits normally, all three of these arguments will be None.

If an exception occurs and is passed to the __exit__ method, the method can return True in order to suppress the exception, or the exception will be re-raised at the end of the __exit__ function.

with AContextManager() as a:
    print("a is %r" % a)
# Entered
# a is 'A-instance'
# Exited

with AContextManager() as a:
    print("a is %d" % a)
# Entered
# Exited (with an exception)
# Traceback (most recent call last):
#   File "<stdin>", line 2, in <module>
# TypeError: %d format: a number is required, not str

Note that in the second example even though an exception occurs in the middle of the body of the with-statement, the __exit__ handler still gets executed, before the exception propagates to the outer scope.

If you only need an __exit__ method, you can return the instance of the context manager:

class MyContextManager:
    def __enter__(self):
        return self

    def __exit__(self):