Exceptions

Beautiful Code
Ka-Ping Yee, February 26, 2003

Whenever you see an error and a traceback, that's caused by an exception.

You can cause an exception with the raise keyword.

>>> raise TypeError
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError
>>> 

Raising an exception is the correct thing to do when you have encountered an unexpected situation. If your code does not have a way to fully recover from an unexpected state, it should abort with an exception as early as possible.

To avoid quitting the entire program, you can catch exceptions using try .... except. If an exception happens, the rest of the try block is skipped. If there is a matching except that corresponds to the kind of exception that was raised, execution jumps to that except block.

>>> try:
...     print 'hello'
...     raise TypeError
...     print 'this gets skipped'
... except TypeError:
...     print 'caught it'
... 
hello
caught it
>>> 

A try ... except construction catches any exceptions that occur during the execution of the try block, even in functions called within the try block.

In the following example, an exception occurs nine levels deep.

>>> def booboo(x):
...     y = 1 / x
...     booboo(x - 1)
... 
>>> booboo(8)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in booboo
  File "<stdin>", line 3, in booboo
  File "<stdin>", line 3, in booboo
  File "<stdin>", line 3, in booboo
  File "<stdin>", line 3, in booboo
  File "<stdin>", line 3, in booboo
  File "<stdin>", line 3, in booboo
  File "<stdin>", line 3, in booboo
  File "<stdin>", line 2, in booboo
ZeroDivisionError: integer division or modulo by zero
>>> 

A single try ... except pair can catch the exception.

>>> try:
...     booboo(8)
... except ZeroDivisionError:
...     print 'caught it'
... 
caught it
>>> 

The exception could occur in another function, in a class method, inside another module, or anywhere, and it would still be caught.