Thoughts on Programming

June 25, 2011

Python: Exception handling

Filed under: Python — shadiyya @ 4:30 am

In a program, even if a statement or expression is syntactically correct, it may cause an error when an attempt is made to execute it. Errors detected during execution are called exceptions. All modern computer languages, and most ancient ones, have built-in constructs and methods for the handling errors or exceptions. Errors will couse the program to fail or produce meaningless results. Most exceptions are not handled by programs, however, and result in error messages as shown here:

>>> 10 * (1/0)
Traceback (most recent call last):
File “”, line 1, in ?
ZeroDivisionError: integer division or modulo by zero
>>> 4 + spam*3
Traceback (most recent call last):
File “”, line 1, in ?
NameError: name ‘spam’ is not defined
>>> ‘2’ + 2
Traceback (most recent call last):
File “”, line 1, in ?
TypeError: cannot concatenate ‘str’ and ‘int’ objects
The last line of the error message indicates what happened. Exceptions come in different types, and the type is printed as part of the message: the types in the example are ZeroDivisionError, NameError and TypeError. The rest of the line provides detail based on the type of exception and what caused it.

Handling exceptions

In Python a programmer can raise an exception at any point in a program. Python scripts can get away from errors by wrapping a portion of the main program in an exception handler to print a nicely formatted error.
The above example, asks the user for input until a valid integer has been entered, but allows the user to interrupt the program.
>>> while True:
…         try:
…             x = int(raw_input(“Please enter a number: “))
…             break
…         except ValueError:
…             print “That was not a valid number. Try again…”

The try statement works as follows:

  • First, the try clause (the statement(s) between the try and except keywords) is executed.
  • If no exception occurs, the except clause is skipped and execution of the try statement is finished.
  • If an exception occurs during execution of the try clause, the rest of the clause is skipped. Then if its type matches the exception named after theexcept keyword, the except clause is executed, and then execution continues after the try statement.
  • If an exception occurs which does not match the exception named in the except clause, it is passed on to outer try statements; if no handler is found, it is an unhandled exception and execution stops with a message as shown above.

A try statement may have more than one except clause, to specify handlers for different exceptions. At most one handler will be executed. An except clause may name multiple exceptions as a parenthesized tuple also. The last except clause may omit the exception name, to serve as a wildcard. For example:

try:

f = open(‘myfile.txt’)
s = f.readline()
i = int(s.strip())
except ValueError:
print “Could not convert data to an integer.”

except:

print “Unexpected error:”

The try … except statement has an optional else clause, which, when present, must follow all except clauses. It is useful for code that must be executed if the try clause does not raise an exception.
>>> for arg in sys.argv[1:]:
…          try:
…                f = open(arg, ‘r’)
…          except IOError:
…               print ‘cannot open’, arg
…          else:
…               print arg, ‘has’, len(f.readlines()), ‘lines’
…               f.close()

When an exception occurs, it may have an associated value, also known as the exception’s argument. The presence and type of the argument depend on the exception type. Exception handlers don’t just handle exceptions if they occur immediately in the try clause, but also if they occur inside functions that are called (even indirectly) in the try clause. For example:
>>> def this_fails():
…           x = 1/0

>>> try:
…          this_fails()
… except ZeroDivisionError as detail:
…          print ‘Handling run-time error:’, detail

Handling run-time error: integer division or modulo by zero

Raising Exceptions
The raise statement allows the programmer to create an exception. The argument to raise indicates the exception to be raised. This must be either an exception instance or an exception class (a class that derives fromException). If we want to determine whether an exception was raised but don’t intend to handle it, just a raise statement allows us to re-raise the exception.
>>> try:
…          raise NameError(‘HiThere’)
… except NameError:
…          print ‘An exception flew by!’
…          raise

An exception flew by!
Traceback (most recent call last):
File “”, line 2, in ?
NameError: HiThere

User-defined exceptions
We can define new exception classes. When creating a module that can raise several distinct errors, it is a good idea to create a base class for exceptions defined by that module, and subclass to create specific exception classes for different error conditions.

class Error(Exception):

“””Base class for exceptions in this module.”””
pass

class InputError(Error):

“””Exception raised for errors in the input.
Attributes:
expr — input expression in which the error occurred
msg — explanation of the error
“””

def __init__(self, expr, msg):

self.expr = expr
self.msg = msg

class TransitionError(Error):

“””Raised when an operation attempts a state transition that’s not
allowed.
Attributes:
prev — state at beginning of transition
next — attempted new state
msg — explanation of why the specific transition is not allowed
“””

def __init__(self, prev, next, msg):

self.prev = prev
self.next = next
self.msg = msg

Cleaning up
The try statement has another optional clause which is intended to define clean-up actions that must be executed under all circumstances.
>>> try:
…          raise KeyboardInterrupt
… finally:
…          print ‘Goodbye, world!’

Goodbye, world!
KeyboardInterrupt
A ‘finally’ clause is always executed before leaving the try statement, whether an exception has occurred or not.

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Create a free website or blog at WordPress.com.