What's the use of the else in try/except/else?

Carl Banks pavlovevidence at gmail.com
Tue May 12 23:04:41 CEST 2009


On May 12, 2:35 am, Steven D'Aprano
<ste... at REMOVE.THIS.cybersource.com.au> wrote:
> On Tue, 12 May 2009 09:20:36 +0000, Steven D'Aprano wrote:
> > On Tue, 12 May 2009 20:23:25 +1200, Lawrence D'Oliveiro wrote:
>
> >> In message <gu7f97$mt... at reader1.panix.com>, kj wrote:
>
> >>> I know about the construct:
>
> >>> try:
> >>>     # do something
> >>> except ...:
> >>>     # handle exception
> >>> else:
> >>>     # do something else
>
> >>> ...but I can't come with an example in which the same couldn't be
> >>> accomplished with [no else]
>
> >> I'd agree. If you have to resort to a "try .. else", then might I
> >> respectfully suggest that you're using exceptions in a way that's
> >> complicated enough to get you into trouble.
>
> > try:
> >     rsrc = get(resource)
> > except ResourceError:
> >     log('no more resources available')
> >     raise
> > else:
> >     do_something_with(rsrc)
> > finally:
> >     rsrc.close()
>
> Except of course such a pattern won't work, because if get(resource)
> fails, rsrc will not exist to be closed. So a better, and simpler,
> example would be to drop the finally clause:

Resource acquisition goes outside the try block.  If you want to log
an error, then get() goes inside its own try block.

try:
    rsrc = get(resource)
except ResourceError:
    log('no more resources available')
    raise
try:
    do_something_with(rsrc)
finally:
    rsrc.close()


If you hadn't reraised the exception, then the else clause would have
been useful as follows:

try:
    rsrc = get(resource)
except ResourceError:
    proceed_without_resource()
else:
    try:
        proceed_with_resource()
        # Note: proceed_with_resource() can possibly raise
        # ResourceError itself
    finally:
        rsrc.close()

The main reason for the else clause on try blocks is so that you don't
risk catching spurrious exceptions.  You could stick
proceed_with_resource() in the try clause, but then if
proceed_with_resource() throws ResourceError because it tries to
acquire a different resource and fails, then it'd be caught and
proceed_without_resource() would be called, which is a mistake.

In general, you want to limit the contents of a try clause to code
that throws an exception you want to catch (if you're trying to catch
an exception); everything else should go into the else clause.

Incidentally, I can't think of any realistic use cases for using all
four of try...except...else...finally.


Carl Banks



More information about the Python-list mailing list