Python for Developers

First Edition

Chapter 13: Exceptions


When a failure occurs in the program (such as division by zero, for example) at runtime, an exception is generated. If the exception is not handled, it will be propagated through function calls to the main program module, interrupting execution.

In [1]:
print 1/0
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-1-e19d6e6ac7e1> in <module>()
----> 1 print 1/0

ZeroDivisionError: integer division or modulo by zero

The try instruction allows exception handling in Python. If an exception occurs in a block marked by try, it is possible to handle the exception through the instruction except. It is possible to have many except blocks for the same try block.

In [1]:
try:
    print 1/0
except ZeroDivisionError:
    print 'Error trying to divide by zero.'
Error trying to divide by zero.

If except receives the name of an exception, only that exception will be handled. If no exception name is passed as a parameter, all exceptions will be handled.

Example:

In [2]:
import traceback

# Try to get a file name
try:
    fn = raw_input('Nome do arquivo: ').strip()

    # Numbering lines
    for i, s in enumerate(file(fn)):
        print i + 1, s,

# If an error happens
except:

    # Show it on the screen
    trace = traceback.format_exc()

    # And save it on a file
    print 'An error happened:\n', trace
    file('trace.log', 'a').write(trace)

    # end the program
    raise SystemExit
Nome do arquivo: test
An exception has occurred, use %tb to see the full traceback.

SystemExit
An error happened:
Traceback (most recent call last):
  File "<ipython-input-2-9b040ca279e5>", line 8, in <module>
    for i, s in enumerate(file(fn)):
IOError: [Errno 2] No such file or directory: 'test'

To exit: use 'exit', 'quit', or Ctrl-D.

The module traceback offers functions for dealing with error messages. The function format_exc() returns the output of the last exception formatted in a string.

The handling of exceptions may have an else block, which will be executed when no exception occurs and a finally block, which will be executed anyway, whether an exception occurred or not. New types of exceptions may be defined through inheritance of the class Exception.

Since version 2.6, the instruction with is available, that may replace the combination of try / finally in many situations. It is possible to define an object that will be used during the with block execution. The object will support the context management protocol, which means that it will need to have an __enter__() method, which will be executed at the beginning of the block, and another called __exit__(), which will be called at the end of the block.

Example:

In [3]:
import random

# Creates a file with 25 random numbers
with file('temp.txt', 'w') as temp:
    for y in range(5):
        for x in range(5):
            # "print >> " records command output on the file
            print >> temp, '%.2f' % random.random(),
        print >> temp

# Shows file content
with file('temp.txt') as temp:
    for i in temp:
        print i,

# Out of the blocks, the file will be closed
# The following command generates an exception ValueError: I/O operation on closed file
print >> temp
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-3cfc563cde8a> in <module>()
     16 # Out of the blocks, the file will be closed
     17 # This generates an exception ValueError: I/O operation on closed file
---> 18 print >> temp

ValueError: I/O operation on closed file
0.06 0.66 0.01 0.94 0.58
0.93 0.72 0.14 0.88 0.50
0.74 0.34 0.64 0.51 0.95
0.35 0.87 0.10 0.02 0.21
0.66 0.92 0.66 0.46 0.82

With file closed at the end of the block, the record attempt generates an exception.

In [1]:
 
Out[1]: