Generators are one of the most influential Python mechanics.
They have many uses, and one of them is to create context managers easily.
Usually, you have to manually define
__exit__ magic methods,
but @contextmanager decorator from
contextlib makes it far more convenient:
from contextlib import contextmanager @contextmanager def atomic(): print('BEGIN') try: yield except Exception: print('ROLLBACK') else: print('COMMIT')
atomic is a context manager that can be used like this:
In : with atomic(): ...: print('ERROR') ...: raise RuntimeError() ...: BEGIN ERROR ROLLBACK
@contextmanager magic allows to use it as a decorator as well as a context manager:
In : @atomic() ...: def ok(): ...: print('OK') ...: In : ok() ...: BEGIN OK COMMIT