[Q] Are Exceptions used that much in practice?

Alex Martelli aleaxit at yahoo.com
Tue Dec 12 03:09:09 EST 2000


"Jerome Mrozak" <goose at enteract.com> wrote in message
news:3A35D546.A4731B5B at enteract.com...
> I realize that Python allows me to catch exceptions.  But being a novice
> I'm not sure if they are used much in the 'real world'.

Oh yes they are -- an absolutely crucial and fundamental technique.


> In Java, my current bread-winning language, exceptions are caught mostly
> because the compiler/language demands it.  I haven't yet designed a

To be specific: in Java, if a certain method's body can raise
certain exceptions it does not catch, you have to _declare_ this
as a part of the method's signature.  A very good design choice
within a language hinging on compile-time static typechecking,
and vastly superior to C++'s semantics for exception declarations
(which were hampered by the need for backwards compatibility).


> Another way of putting it is, if the try-catch-else didn't exist would
> anyone be terribly put out?  (If not then the construct isn't much
> used...)

Python programming would be utterly different (and much less fun)
if one could not use try/except.  (try/finally could more easily
be replaced by a slightly different semantics on guaranteed
finalization of objects, and it's a pity a 'try' can't have one
or more 'except' clauses _followed_ by a 'finally' one, etc, etc,
but these are secondary issues).

Specifically: in Python, exceptions are NOT for 'exceptional'
conditions ONLY (as good programming style demands they be in
C++, and, ideally, in Java just as well).  exceptions are the
NORMAL Python way to report on "I can't do this, Jim".

You want to exit from a deeply-nested loop, or recursion?  Use
exceptions.  You want to terminate a tree-walk over directories?
Use exceptions.

Perhaps the single most important issue is the design pattern
named (after a famous quote from Commodore Hopper, Cobol's
inventor) "It's easier to ask forgiveness than permission".

A typical setting for it: somebody asks, "How do I check that
a file exists?".  What they most often MEAN by this: 'how do
I check that a file exists AND is authorized to be read by
the user currently running the program AND THEN actually go
and open the file for reading?" -- and the best answer to this
question is NOT, e.g.:

def open_if_ok1(filepath):
    if os.access(filepath, os.R_OK):
        return open(filepath, 'r')
    else:
        return None

Why not?  Well, for example, the world is multi-tasked: there
is a small but non-null window of time between the instant
in which os.access gives you the go-ahead, and the following
instant in which you actually go and 'use' that permission!
The file *might* go away or get locked against reading in
that small window -- the kind of problem, connected with 'race
conditions', that's EXCEEDINGLY hard to pinpoint, reproduce,
and debug, when it comes up...

There is a simpler, safer, sounder way...:

def open_if_ok2(filepath):
    try: return open(filepath, 'r')
    except IOError: return None

"Just do it" -- making sure expected possible errors are
caught and handled in according with the semantic specs
(here, we assume, None is to be returned if the filepath
can't be opened for reading, for whatever reason).


Or, take another example.  "Am I allowed to set attribute
foo of object bar to the Unicode string u'fee fie foo fum'"?

How do you check for *that*, when the object can have any
type, and, if it's an instance-object, its __setattr__ might
do whatever kinds of semantic checks on the attribute being
set and/or the value it's being set to...?

'Asking for permission' is basically unfeasible here.  Much
better to 'ask for forgiveness' if needed, e.g.:

def setattr_ok(obj, attr, value):
    try: setattr(obj, attr, value)
    except (AttributeError, ValueError): return 0
    else: return 1

(Some might prefer a wider 'except: return 0' clause, but
most often it's better to be specific in catching exceptions).


Alex






More information about the Python-list mailing list