The Standard Exception Hierarchy
Python comes filled with many built-in exceptions. All these exceptions are part of the exceptions module, which is always loaded prior to any program execution.
The following structure identifies the standard exception hierarchy, and, immediately afterwards, it is given the description of each exception type.
This structure, which resembles a tree, shows you that all exceptions are derived from a base class named Exception. If we highlight, for example, the ImportError exception, we note that it is a subclass of the StandardError class. In addition to that, the StandardError class is a subclass of the Exception class. Table 4.1 shows the structure.
Table 4.1. The Exception Class Hierarchy
Exception
|
SystemExit
|
StandardError
|
KeyboardInterrupt
|
ImportError
|
EnvironmentError
IOError
OSError
|
EOFError
|
RuntimeError
NotImplementedError
|
NameError
UnboundLocalError
|
AttributeError
|
SyntaxError
|
TypeError
|
AssertionError
|
LookupError
IndexError
KeyError
|
ArithmeticError
OverflowError
ZeroDivisionError
FloatingPointError
|
ValueError
|
SystemError
|
MemoryError
|
Exception
This is the root class. All exception classes are subclasses of this base class. Every user exception class should be derived from this class too.
SystemExit
This is an exception because it isn't really an error message. Instead, it can be used to exit a program. The important thing is that this exception doesn't return any traceback message.
StandardError
It is the base class for all errors (except for SystemExit, of course).
KeyboardInterrupt
It is raised when an interrupt key, such as CTRL+C, is pressed.
ImportError
It is raised when Python cannot find a module to import.
EnvironmentError
This is the base class for errors that occur outside the Python environment. The IOError and OSError classes subclass it.
IOError
It is raised by I/O operation errors.
OSError
This one is raised by operating system errors, usually generated by the os module.
EOFError
Exception raised when an End-of-File (EOF) error occurs.
RuntimeError
This is a special type of exception raised by errors that aren't covered by any of the other exceptions.
NotImplementedError
Methods or functions that aren't implemented should raise this exception.
>>> def updateregistry():
>>> raise NotImplementedError
NameError
It is raised when the interpreter finds a name that is neither in the local nor in the global namespace.
UnboundLocalError
This is a new exception that was created for version 1.6. It subclasses the NameError exception, raising an error when a local variable is undefined.
AttributeError
It is raised by attribute reference and attribute assignment kinds of errors. Note that starting with version 1.6, this exception will have a more friendly error message, which is expected to break some code that assumes the message to be exactly equivalent to the attribute name.
SyntaxError
It is raised by syntax errors.
TypeError
This exception is raised when you try to apply a function operation to an object of inappropriate type.
AssertionError
This kind of exception is raised when an assert statement fails by evaluating to false.
LookupError
This is the base class for indexing and key errors. The IndexError and KeyError classes subclass it.
IndexError
It is raised by "sequence out of range" errors.
KeyError
It is raised when a key is not found in a dictionary.
ArithmeticError
This is the base class for arithmetic errors. The classes OverflowError,
ZeroDivisionError, and FloatingPointError subclass it.
OverflowError
This exception is raised when the result is so large that it makes the operation overflow.
ZeroDivisionError
It is raised when an operation that tries to divide a number by zero is performed.
FloatingPointError
This exception is raised by floating-point operation errors. Note that on Linux systems, you are required to enable the SIGFPE handling with the fpectl module to use this exception.
ValueError
This one is raised when you try to perform an action using the right type but the wrong value.
SystemError
It is raised if a Python's interpreter internal error takes place.
MemoryError
This exception is raised by a recoverable out-of-memory error.
As exception classes are grouped within other exception classes (known as base classes), it becomes much easier to catch several different types of errors/exceptions by using just one except clause.
Base classes are never raised, but can be used to catch up errors.
The next scenario shows how to cover multiple exceptions by declaring only the base class exception.
>>> dict = { 1:"First Element",2:"Second Element"}
>>> list = [13,14,15,16]
Based on these structures, we get the following error messages when we try any out-of-range type of operations.
>>> dict[3]
Traceback (innermost last):
File "<stdin>", line 1, in ?
KeyError: 3
>>> list[8]
Traceback (innermost last):
File "<stdin>", line 1, in ?
IndexError: list index out of range
The following example is able to catch both IndexError and KeyError exceptions.
>>> def getelement(element):
>>> try:
>>> if element < 10:
>>> print dict[element]
>>> else:
>>> print list[element]
>>> except LookupError:
>>> print "Sorry. This element does not exist"
>>> getelement(1)
First Element
>>> getelement(20)
Sorry. This element does not exist
Now, let's talk about release 2.0. Check the next code.
def showcounter():
print "counter=", counter
counter = counter + 1
showcounter()
The previous code raises an exception on the print statement in both 1.5.2 and 2.0 release. However, in 1.5.2 a NameError exception is raised, while in 2.0 a new exception is raised. This new exception is called UnboundLocalError, which is a subclass of the NameError exception.
Talking about new exceptions, the Python 2.0 release comes with two more brand-new exceptions. They are called TabError and IndentationError, and they are subclasses of the SyntaxError exception.