What's the use of the else in try/except/else?
Carl Banks
pavlovevidence at gmail.com
Tue May 12 17:04:41 EDT 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