Python Language Ecrire votre propre gestionnaire de contexte en utilisant la syntaxe du générateur


Exemple

Il est également possible d'écrire un gestionnaire de contexte en utilisant la syntaxe du générateur grâce au décorateur contextlib.contextmanager :

import contextlib

@contextlib.contextmanager
def context_manager(num):
    print('Enter')
    yield num + 1
    print('Exit')

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))

produit:

Enter
Right in the middle with cm = 3
Exit

Le décorateur simplifie l'écriture d'un gestionnaire de contexte en convertissant un générateur en un seul. Avant que l'expression de rendement ne devienne la méthode __enter__ , la valeur __enter__ devient la valeur renvoyée par le générateur (qui peut être liée à une variable dans l'instruction with), et tout ce qui suit l'expression de rendement devient la méthode __exit__ .

Si une exception doit être gérée par le gestionnaire de contexte, un try..except..finally -block peut être écrit dans le générateur et toute exception déclenchée dans le bloc with -block sera traitée par ce bloc d'exception.

@contextlib.contextmanager
def error_handling_context_manager(num):
    print("Enter")
    try:
        yield num + 1
    except ZeroDivisionError:
        print("Caught error")
    finally:
        print("Cleaning up")
    print("Exit")

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

Cela produit:

Enter
Dividing by cm = 0
Caught error
Cleaning up
Exit