Bare Excepts

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sat Jan 2 05:42:17 EST 2010


On Fri, 01 Jan 2010 15:27:57 -0800, myle wrote:

> Why we should prefer ``if: ...'' over  a ``try: ... except something:
> pass'' block?

We shouldn't, not in general.

Often, the if test is just as expensive as actually doing it. E.g.:

if x in mylist:
    position = mylist.index(x)
else:
    do_something()

has to search the list twice, first to see if x is there, then search it 
again to return the index. That does double the work needed. A better way 
is:

try:
    position = mylist.index(x)
except ValueError:
    do_something()

unless you expect that x is often missing: setting up the try block is 
much faster than the test, but catching the exception is much, much 
slower. So long as exceptions are rare, it is better to use the try 
version (also known as "Better to ask forgiveness than permission"). But 
if exceptions are common, it may be better to use the if version ("Look 
before you leap").

The try version is also better whenever there could be a race condition. 
For example, when opening a file, you might be tempted to do this:

if os.path.exists(filename):
    f = open(filename, 'r')
    text = f.read()
else:
    print "file missing"

but that is dangerous in a multi-processing computer system (which nearly 
all computers are these days). The problem is that in the fraction of a 
second after you test that the file exists, some other process might come 
along and delete it and the open call will then fail. So to be safe, you 
have to do this:

if os.path.exists(filename):
    try:
        f = open(filename, 'r')
    except IOError:
        print "file missing"
    else:
        text = f.read()
else:
    print "file missing"


But of course now the test is redundant, and all you really need is the 
try...except block:

try:
    f = open(filename, 'r')
except IOError:
    print "file missing"
else:
    text = f.read()


(Note: the above is still not entirely robust. For example, if you try to 
read a file that you don't have permission to read, it wrongly reports it 
is missing instead of a permissions error. To make this more robust, you 
need to inspect the exception and check the error code.)



-- 
Steven



More information about the Python-list mailing list