Alex Rivera | Logout

Python Exceptions: EAFP and What is Really Exceptional?

Asked 2010-06-21T17:13:49.313
18

It's been said in a couple places (here and here) that Python's emphasis on "it's easier to ask for forgiveness than permission" (EAFP) should be tempered with the idea that exceptions should only be called in truly exceptional cases. Consider the following, in which we're popping and pushing on a priority queue until only one element is left:

import heapq
...
pq = a_list[:]
heapq.heapify(pq)
while True:
    min1 = heapq.heappop(pq)
    try:
        min2 = heapq.heappop(pq)
    except IndexError:
        break
    else
        heapq.heappush(pq, min1 + min2)
# do something with min1

The exception is only raised once in len(a_list) iterations of the loop, but it's not really exceptional, because we know its going to happen eventually. This setup saves us from checking whether a_list is empty a bunch of times, but (maybe) it's less readable than using explicit conditions.

What's the consensus on using exceptions for this kind of non-exceptional program logic?

Edit
Report

1 Answer

7

Looking at the docs I think you can safely re-write the function as follows:

import heapq
...
pq = heapq.heapify(a_list)
while pq:
    min1 = heapq.heappop(pq)
    if pq:
        min2 = heapq.heappop(pq)
        heapq.heappush(pq, min1 + min2)
# do something with min1

..and thereby avoid the try-except.

Getting to the end of a list which is something you know is going to happen here isn't exceptional - it's garaunteed! So better practice would be to handle it in advance. If you had something else in another thread which was consuming from the same heap then using try-except there would make a lot more sense (i.e. handling a special / unpredictable case).

More generally, I would avoid try-excepts wherever I can test for and avoid a failure in advance. This forces you to say "I know this bad situation might happen so here's how I deal with it". In my opinion, you'll tend to write more readable code as a result.

[Edit] Updated the example as per Alex's suggestion

answered 2010-06-21T17:21:12.560

Your Answer