Why no try-except-finally ?

Peter Hansen peter at engcorp.com
Wed Nov 5 07:50:01 EST 2003


KefX wrote:
> 
> For now I rewrote it like this, just a modified version of what you suggested:
> 
>     err_code = 0
>     try:
>         game.Play()  # was PlayGame() before
>     except:
>         err_msg = "FATAL ERROR: " + sys.exc_info()[0]
>         logger.critical(err_msg)
>         err_code = 1
> 
>     DeInit()
>     return err_code

Somewhat better style, generally, IMHO, would be to replace "err_code = 1"
with "raise" in the above.  Consider returning error codes to be a
parallel (and somewhat obsolescent) way of communicating failures to
calling code.  Raising an exception should be generally preferred.

Note, however, that doing this (re-raising the exception) brings
you back to your original query as well, as DeInit() would not get
called if it were not in a try/finally.

A second style point: use a general try/except (without specifying
the exceptions to be caught) is usually a Very Bad Idea.  It's okay
at the top level of a module, but it will mask all kinds of bugs
at the lower levels.  For example, in the above you might have
misspelled Play() as play() and you would get an AttributeError,
but would think that it was the call to Play() which had raised
an exception and the "FATAL ERROR".

Again, however, restricting the set of exceptions called means that
in the case where one of the unhandled ones is raised (unhandled at
this particular level, anyway), you still want a finally clause
to ensure DeInit() is executed.

I'd say, in response to the original question, that the nested 
try/except in the try/finally is the appropriate, preferred Pythonic
idiom.

-Peter




More information about the Python-list mailing list