See All Titles |
![]() ![]() Raising ExceptionsThere are several ways to raise exceptions. You can either raise your own exceptions or Python standard exceptions by using any of the four techniques listed as follows:
Note that the second and third forms of raising exceptions use the old form of passing arguments with the exception. I recommended using only the first and fourth forms. Passing None, as the second argument, to the raise statement is equivalent to omitting it. raise class, None is equivalent to raise class() Check the following cases. raise IndexError() raise IndexError raise IndexError("x is out of range") raise IndexError, "x is out of range" In the previous lines, the examples use a standard exception called IndexError. However, you can raise any one of the supported built-in exceptions. Look at another example that uses a different exception: op = raw_input("Enter an operator: ") op1 = input("Enter first operand: ") op2 = input("Enter second operand: ") if op == "+": print op1 + op2 else: raise RuntimeError("I don't know this command") In the next chapter, after learning how you can handle classes, you will be able to easily understand this next example. For the present time, take a deep breath and just have some fun. This example raises an exception that blocks your access to nonexistent members of the c class. 1: >>> class c: 2: … def __init__(self, name): 3: … self.name = name 4: … def __getattr__(self, attr): 5: … if attr <> "name": 6: … raise AttributeError 7: … 8: >>> a = c("Andre") 9: >>> a.name 10: 'Andre' 11: >>> a.age The following traceback message is generated after running the command located at line 11. Traceback (innermost last): File "<stdin>", line 1, in ? File "<stdin>", line 6, in __getattr__ AttributeError As you can see, line 5 checks the name of the attribute that is being passed to the method. That makes the exception in line 6 to always be raised when the attribute name is not "name". However, note that if you assign something to a.age, as demonstrated next, getting the value of a.age will no longer cause the error. To handle that, you would need to write a code to deal with the __setattr__ method, but that would be another example. >>> a.age = 32 >>> print a.age 32 Raising an Exception to Leave the InterpreterRaising the SystemExit exception is a generic way to leave the Python interpreter. C:\Program Files\Python>python Python 1.5.2 (#0, Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)] on win32 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> raise SystemExit C:\Program Files\Python> The next example demonstrates how you can trap the SystemExit exception. >>> try: … raise SystemExit … except SystemExit: … print "Sorry. You can not leave." … Sorry. You can not leave. The sys.exit() function raises an exception SystemExit that, if not caught, causes the thread to exit silently. >>> import sys >>> try: … sys.exit() … except SystemExit: … print "I have already told you. You can not leave." … I have already told you. You can not leave. Raising an Exception to Leave Nested LoopsSometimes you are so deeply involved in your data structures that you only want to get out of all your nested loops quickly. Normally, you would have to use break for each level of interaction. The next example demonstrates how to handle this situation by using exceptions. >>> ExitLoop = "ExitLoop" >>> try: … i=1 … while i < 10: … for j in xrange(1,5): … print i,j … if (i==2) and (j==3): … raise ExitLoop … i = i + 1 … except ExitLoop: … print "i=2 and j=3 is a special case." … 1 1 1 2 1 3 1 4 2 1 2 2 2 3 i=2 and j=3 is a special case. Raising String ExceptionsOlder versions used to support only strings for both Python standard exceptions and user-defined exceptions. >>> NetworkError = "NetworkError" >>> raise NetworkError, "Bad hostname" Nowadays, Python supports both strings and exception classes. There are costs to using class exceptions because they must be instantiated to be caught. Note that most people don't use exceptions to control the flow of their program, so they don't occur much. However, classes give you much more flexibility to generalize the type of error that you want to catch. Instancing an Exception ClassEvery time an exception is raised, an instance of the exception class is created. The next syntax demonstrates how to catch a class instance in your program. try: <statements> except exception, instance: <statements> The instance variable is an instance of the raised exception. Therefore, it inherits attributes from the exception class. Each instance has an attribute called args that returns the error string in a tuple format. >>> try: … a = [1,2] … print a[4] … except IndexError, b: … print b.args … ('list index out of range',) Particularly, the EnvironmentError exception has a 2-tuple or 3-tuple structure that can be translated as (error number, string error message, and an optional filename). >>> try: … file = open("Parrot") … except EnvironmentError, b: … print b.args … (2, 'No such file or directory') When the instance belongs to a SyntaxError class exception, four special attributes are also returned: filename, lineno, offset, and text. >>> try: … a = "x===10" … exec a … except SyntaxError, b: … print b.args … ('invalid syntax', (None, 1, 4, 'x===10')) Note
Modules are parsed before being run, so syntax errors in a file can't be caught by try/except blocks that surround the error. You can catch it from the bit of code that imported the module, however. Debugging Your CodeExceptions are very good for helping to debug your code. You can use the assert command to raise a debugging exception that transports a message to your exception handling code. The syntax is assert <TestStatement> [,argument] This command raises an AssertionError exception whenever <TestStatement> evaluates to false. For example >>> def divide (a,b): … assert b != 0, "Can't divide by zero" … return a/b >>> >>> divide(10,0) Traceback (innermost last): File "<stdin>", line 1, in ? File "<stdin>", line 2, in divide AssertionError: Can't divide by zero The assert command is equivalent to >>> if __debug__:c >>> if not (<TestStatement>): >>> raise AssertionError [, argument] __debug__ is a built-in name and has its value set to true by default. To set __debug__ to false, it is necessary to change the interpreter to run in optimized mode. Tip
Calling the interpreter with the -O option activates the optimized mode. c:\>python -O Currently, Python's command-line option -X turns all standard exceptions into strings. Version 1.6 is expected to have this option removed, and make all standard exceptions into classes. User code that deals with string exceptions will still be supported, but not encouraged. See Chapter 17, "Development Tools," for more details about other command-line options that you can transport as configuration parameters to the interpreter.
|
Index terms contained in this section[nd]O option[nd]X option args attribute assert command 2nd attributes args catching class instances class instances catching classes exception instancing 2nd code debugging exceptions commands assert 2nd debugging code exceptions EnvironmentError exception exception classes instancing 2nd exceptions EnvironmentError IndexError raising 2nd 3rd 4th 5th string raising SyntaxError SystemExit 2nd functions raise class() sys.exit() IndexError exception instance variable instances class catching instancing exception classes 2nd interpreters raising exceptions to leave modes optimized modules parsing optimized mode options [nd]O [nd]X parsing modules raise class() function raise statement raising exceptions 2nd 3rd 4th 5th source code debugging exceptions statements raise try/except string exceptions raising syntax commands assert command SyntaxError exception sys.exit() function SystemExit exception 2nd try/except statement variables instance |
© 2002, O'Reilly & Associates, Inc. |