@contextmanager decorator
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 __enter__
and __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')
Now atomic
is a context manager that can be used like this:
In : with atomic():
...: print('ERROR')
...: raise RuntimeError()
...:
BEGIN
ERROR
ROLLBACK
Additionally, the @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