Defining New Exceptions - Page 4
September 14, 2001
All the built-in exceptions are defined in terms of classes. To
create a new exception, create a new class definition that
inherits from exceptions.Exception such as the
following:
import exceptions
# Exception class
class NetworkError(exceptions.Exception):
def __init__(self,args=None):
self.args =args
The name args should be used as shown. This allows
the value used in the raise statement to be properly
printed in tracebacks and other diagnostics. In other words,
raise NetworkError, "Cannot find host."
creates an instance of NetworkError using the call
NetworkError("Cannot find host.")
The object that is created will print itself as
NetworkError:Cannot find host. If you use a name
other than self.args or you don't store the
argument, this feature won't work correctly.
When an exception is raised, the optional value supplied in the
raise statement is used as the argument to the
exception's class constructor. If the constructor for an
exception requires more than one argument, it can be raised in
two ways:
import exceptions
# Exception class
class NetworkError(exceptions.Exception):
def __init__(self,errno,msg):
self.args =(errno,msg)
self.errno =errno
self.errmsg =msg
# Raises an exception (multiple arguments)
def error2():
raise NetworkError(1,'Host not found ')
# Raises an exception (multiple arguments)
def error3():
raise NetworkError,(1,'Host not found ')
Class-based exceptions enable you to create hierarchies of
exceptions. For instance, the NetworkError exception
defined earlier could serve as a base class for a variety of more
specific errors. For example:
class HostnameError(NetworkError):
pass
class TimeoutError(NetworkError):
pass
def error3():
raise HostnameError
def error4():
raise TimeoutError
try:
error3()
except NetworkError:
import sys
print sys.exc_type # Prints exception type
In this case, the except NetworkError statement
catches any exception derived from NetworkError. To
find the specific type of error that was raised, examine the
variable sys.exc_type. Similarly, the
sys.exc_value variable contains the value of the
last exception. Alternatively, the sys.exc_info()
function can be used to retrieve exception information in a
manner that doesn't rely on global variables and is thread-safe.
Assertions and __debug__
The assert statement is used to add debugging code
into a program. The general form of assert is
assert test [,data ]
where test is an expression that should evaluate to true or
false. If test evaluates to false,
assert raises an AssertionError
exception with the optional data supplied to the
assert statement. For example:
def write_data(file,data):
assert file,"write_data:file is None!"
...
Internally, the assert statement is translated into
the following code:
if __debug__:
if not (test ):
raise AssertionError,data
__debug__ is a built-in read-only value that's set
to 1 unless the interpreter is running in optimized
mode (specified with the -O option). Although
__debug__ is used by assertions, you also can use it
to include any sort of debugging code.
The assert statement should not be used for code
that must be executed to make the program correct, since it won't
be executed if Python is run in optimized mode. In particular,
it's an error to use assert to check user input.
Instead, assert statements are used to check things
that should always be true; if one is violated, it represents a
bug in the program, not an error by the user.
For example, if the function write_data() shown here
were intended for use by an end user, the assert statement should
be replaced by a conventional if statement and the desired error
handling.
Built-in Exceptions - Page 3
Python Essential Reference, Second Edition
|