[Tutor] Newbie Question on Exceptions...

John Fouhy john at fouhy.net
Wed May 9 06:28:01 CEST 2007


On 09/05/07, dsh0105 at comcast.net <dsh0105 at comcast.net> wrote:
> try:
>     print "The fridge contains %s" %fridge[food_sought]
> except (KeyError):
>     print "The fridge does not contain %s"%food_sought
[...]
> Is the same true of Python? Or is ok to use Exception handling like the book suggests?

This general debate is called "look before you leap" vs "easier to ask
forgiveness than permission".  If you google for "python eafp lbyl"
you will get a zillion pages of people debating it.  Here's a quote
from a post by Alex Martelli
(http://en.wikipedia.org/wiki/Alex_Martelli):

# from http://mail.python.org/pipermail/python-list/2003-May/205182.html
"""
There are umpteen good reasons why EAFP is vastly superior to LBYL.  For
example, we can just focus on the fact that these days we work mostly on
multiprogrammed machines.  While script A is running, some other programs
B, C, D, ... are typically also running -- and they might be mucking
with the same directories and/or files that A is working with.

So, if A's structure is:

    if iswhatiwant(thefile):
        useappropriately(thefile)
    else:
        dealwithwrongness()

then A is buggy.  That is because, between the moment in which the test
'iswhatiwant' runs (and returns a true value), and the later moment in
which procedure 'useappropriately' runs, *just about anything may have
happened* -- in particular, some other program Z might have removed or
modified 'thefile' so that it's NOT what A wants any more.  I.e., A may
lose control of the CPU between the moment it tests and the later time
in which it uses the result of that test.

This is known as a "race condition" and it's among the hardest problems
you may run into.  A may seem to be running just fine 99 times and then
the 100th time BOOM -- because of accidents of timing between A and
other stuff that may be running "at the same time"... a "race", so to
speak, whence the name whereby this horrid condition is known.

Fortunately, in a language with good support for exceptions such as
Python, you are NOT doomed to enter the hell of race conditions -- just
use EAFP instead of LBYL:

    try:
        useappropriately(thefile)
    except ItWasWrong, howwasitwrong:
        dealwithwrongness()

See how deeply simpler this is?  'useappropriately' just ASSUMES the
file is 'what A wants' and raises an ItWasWrong exception if the
assumption proves to be unfounded.  You don't have to code a
separate 'iswhatiwant' test -- what you DO want is determined inherently
by what 'useappropriately' tries to do.  No race conditions, no code
that must duplicate the set of conditions to be checked for, no
duplicate work at runtime in terms of system calls to determine
if a condition holds followed by system calls to take advantaqe
of that condition.

This risks leaving the impression that EAFP is a panacea - it isn't,
and it has its own issues to watch for -- it's simply heads and
shoulders above LBYL in most practical cases.  Please see my more
detailed discussions of this in the Cookbook and the Nutshell for
something more about error-checking strategies.
"""

-- 
John.


More information about the Tutor mailing list