Python Language Context Managers (“with” Statement) Writing your own contextmanager using generator syntax

Help us to keep this website almost Ad Free! It takes only 10 seconds of your time:
> Step 1: Go view our video on YouTube: EF Core Bulk Insert
> Step 2: And Like the video. BONUS: You can also share it!


It is also possible to write a context manager using generator syntax thanks to the contextlib.contextmanager decorator:

import contextlib

def context_manager(num):
    yield num + 1

with context_manager(2) as cm:
    # the following instructions are run when the 'yield' point of the context
    # manager is reached.
    # 'cm' will have the value that was yielded
    print('Right in the middle with cm = {}'.format(cm))


Right in the middle with cm = 3

The decorator simplifies the task of writing a context manager by converting a generator into one. Everything before the yield expression becomes the __enter__ method, the value yielded becomes the value returned by the generator (which can be bound to a variable in the with statement), and everything after the yield expression becomes the __exit__ method.

If an exception needs to be handled by the context manager, a try..except..finally-block can be written in the generator and any exception raised in the with-block will be handled by this exception block.

def error_handling_context_manager(num):
        yield num + 1
    except ZeroDivisionError:
        print("Caught error")
        print("Cleaning up")

with error_handling_context_manager(-1) as cm:
    print("Dividing by cm = {}".format(cm))
    print(2 / cm)

This produces:

Dividing by cm = 0
Caught error
Cleaning up

Got any Python Language Question?