[Tutor] Terminology question

Steven D'Aprano steve at pearwood.info
Sat May 16 19:57:16 CEST 2015


On Sat, May 16, 2015 at 09:56:33AM -0700, Jim Mooney Py3.4.3winXP wrote:

> def make_error():
>     raise ZeroDivisionError('Here I am')
> 
> def call_error():
>     try:
>         make_error()
>     except:
>         print("How do I get the 'Here I am' message to print in the calling
> routine?")

Okay, here is a hint for you:

Every time you use a bare "except", god kills a puppy. Please, won't you 
think of the poor little puppies?

All joking aside, using a bare except is *nearly always* not what you 
want, and poor practice. The problem is that it catches too much, and so 
masks bugs that should be fixed. You should only catch exceptions that 
you know about and that you can recover from. Everything else is an 
indication that your code has a bug that needs fixing.

But, having said that, sometimes I'm lazy too, and when experimenting at 
the interactive interpreter, I just write "except:" without specifying a 
specific exception. Just don't let it become a habit in real code.


> >>> call_error()
> How do I get the 'Here I am' message to print in the calling routine?


The easiest and best way is to just *not* catch the exception and let 
Python print a traceback. But if you want to look at the error message 
while recovering from the exception, you have to catch and name the 
exception. You can specify multiple types by using a tuple of exception 
types:

try:
    ...
except (TypeError, ValueError) as err:
    print(err.args[0])


Notice that there is no supported syntax for leaving the exception type 
blank while still naming it.

Remember that exceptions are objects too, and the various exception 
types are classes. You can subclass them to make your own types:

class MyValueError(ValueError):
    pass

raise MyValueError


Also, all exceptions inherit from a single class: BaseException. So you 
can say:

except BaseException as error

which is (nearly[1]) the same as a bare except clause, but giving it a 
name. Normally, however, that's not what you want, since that will also 
catch things like the user typing Ctrl-C to interrupt a infinite loop, 
and other exceptions which don't represent errors.

To just catch errors, use "except Exception as error", then inspect 
error.args[0].




[1] There is one slight difference. Up to Python 2.5, you could raise 
and catch strings as well as exceptions. This turned out to be a bad 
idea, and was finally removed in 2.6. But if you are running 2.5 or 
older, a bare except clause is the only way to catch string exceptions 
unless you know exactly what string it it.


-- 
Steve


More information about the Tutor mailing list