An elegant way to use a resource in Python?
Question: I want to find an elegant way to do the following:

    
    
    try:
        with some_resource:
            # got it
            do_something()
    
    except ResourceUnavailableError:
        # didn't get it
        do_something_else()
    

This:

  1. tries to get a resource
  2. on success, it does something, and then releases the resource correctly
  3. on failure, it does something else

Although not many lines of code, I find that if I have to keep writing this in
many different places, it's not very elegant.

I almost wish I could write something as follows (I know this is not real
Python code):

    
    
    with some_resource:
        # got it
        do_something()
    
    # an optional else
    else:
        # didn't get it
        do_something_else()
    

Does anyone know if it's possible to write something along those lines in
Python? Thanks!!


Answer: No, `with` has no `else` block. But you can write your own context manager
that handles the `else` part:

    
    
    from contextlib import contextmanager
    
    @contextmanager
    def handle_unavailable(resource, exception, exception_handler):
        try:
            with resource:
                 yield resource
        except exception:
            exception_handler()
    

and use it like this everywhere as:

    
    
    with handle_unavailable(some_resource, ResourceUnavailableError, do_something_else):
        do_something()
    

So if `ResourceUnavailableError` is raised in the `with` block,
`do_something_else` is called for you.

This makes use of the [`@contextlib.contextmanager()`
decorator](http://docs.python.org/2/library/contextlib.html#contextlib.contextmanager),
which makes writing your own context managers almost trivial.

