The contextlib.contextmanager function decorator provides a handy way of providing a context manager without the need to write a full-fledged ContextManager
class of your own (with __enter__
and __exit__
methods, so you don’t have to remember the arguments to the __exit__
method, or that the __exit__
method must return True
in order to suppress the exception). Instead, you write a function with a single yield
at the point you want the with
block to run, and you trap any exceptions (that effectively come from the yield
) as you normally would.
from contextlib import contextmanager
@contextmanager
def handler():
# Put here what would ordinarily go in the `__enter__` method
# In this case, there's nothing to do
try:
yield # You can return something if you want, that gets picked up in the 'as'
except Exception as e:
print "no not possible"
finally:
print "Ok I caught you"
with handler():
name="rubicon"/2 #to raise an exception
Why go to the extra trouble of writing a context manager? Code re-use. You can use the same context manager in multiple places, without having to duplicate the exception handling. If the exception handling is unique to that situation, then don’t bother with a context manager. But if the same pattern crops up again and again (or if it might for your users, e.g., closing a file, unlocking a mutex), it’s worth the extra trouble. It’s also a neat pattern to use if the exception handling is a bit complicated, as it separates the exception handling from the main line of code flow.