The exception process uses the try statement in two different forms: the try…except…else statement and the try…finally statement. You’ve already seen a few examples of the first format; the second format provides a simplified operation sequence when you want to act upon an exception, but not actually handle the exception. Let’s look at some examples to make it clearer.
The first form of the try statement acts a bit like an if statement in reverse-you embed a block of code that is executed, and then a number of except statements account for an exception if it occurs. The basic format for this first form is:
try: BLOCK except [EXCEPTION , DATA...]]: BLOCK else: BLOCK
When the Python interpreter encounters a try statement, it follows this basic procedure:
1.The BLOCK under the try statement is executed. If an exception is raised, execution returns immediately to the first except statement.
2. If the exception that was raised matches the EXCEPTION specified-or all exceptions if EXCEPTION is not defined-then the corresponding BLOCK is executed, with the objects defined in DATA being accessible to the handler.
3. If the exception does not match, execution jumps to the next except statement; you can have as many except statements as you like.
4.If no except statement matches, the exception is passed to the next highest try block that called this block.
5.If no exception occurred, the else block is block is mention.
There are a few core components in this process that deserve extra mention.
except Statements Support Multiple Formats
Although it may not be clear from the preceding procedure, you can trap errors and introduce a number of exception handlers in a number of different ways. The except statement accepts five different formats, as outlined in Table 7-1.
except Statements Are Checked in Sequence
In steps 2 and 3 of the exception-handling procedure, you can see that when the exception is raised, each except statement is examined to see if the specified exception matches the exception that occurs. The examination occurs in sequence; Python doesn’t check all the except clauses in one go. This means that you can identify individual exceptions and also classes until you reach the top. You saw an example of this earlier.
|except:||Catch all (or all other) exceptions.|
|except name:||Catch the exception specified by name.|
|except (name1, name2):||Catch all the exceptions listed.|
|except name, data:||Catch the exception and any additional data returned.|
|except (name1,name2),data:||Catch the exceptions listed and any additional data returned.|
The following script looks for a ZeroDivisionError exception and a TypeError, and traps everything else:
def divide(x,y): return x/y def calc(x,y): return x*(divide(x,y)) try: Print calc('Hello',1) except ZeroDivisionError: print "Whoa!: Your trying to divide by zero and you can't!" except TypeError: print "Whoa!: That doesn't look like a number!" except: print "Whoa!: Some other kind of error occurred!"
The important thing to remember is to work from the most-specific exception to least-specific exception. If you’d placed Exception the base class for all exceptions types – in the first except statement, the remaining handlers would not ever have been checked.
Exception Handlers Run Once
If you’ve executed the earlier script, you’ll notice that it’s the TypeError exception that is reported. Even though the general Exception would normally catch all exceptions, there’s been a match-only one match by the try…except…else statement is allowed. As soon as the exception block has been executed, control returns to the statements immediately after the entire try statement, unless, of course, you’ve called another function or one of the exit functions.
else Only Runs When There Are No Exceptions
According to step 5 of the exception-handling procedure, the else statement is only executed if no exceptions occur. Normally you use this in the same way that you might use an if block:
try: file = open('file') except EnvironmentError: print "Whoops: Can't seem to open the file" else: lines file.readline] file.close()
There is no exception to this rule. If you want to run similar statements in an exception handler, you’ll either need to duplicate the statements or create a function to handle them.
Most exceptions include additional information about the cause of an exception in addition to the information about the error itself. For example, consider the following script:
def parsefile(filename): file open(filename, 'rw') print file.readline() file.write('Hello World!") file.close() try: Parsefile('string') except EnvironmentError, (errno,msg): Print "Error: %$ (%d) whilst parsing the file" % (msg,errno)
This script includes a single exception handler for an EnvironmentError; thsi is the base class used for problems encountered by Python when accessing information outside of the Python interpreter, such as the contents of a file. Instead of trying to trap all of the different errors that might occur such as nonexistent files, full file systems, or an end-of-file condition, you can just trap for the generic exception and use the additional information supplied by the exception to further describe the error to the user.
The EnvironmentError exception automatically returns the C library error number and the associated message (if there is one). For example, all of the following are perfectly valid error messages when calling the parsefile function:
Error: No such file or directory (2) whilst parsing the file Error: Bad file descriptor (9) whilst parsing the file Error: No space left on device (28) whilst parsing the file
If you specify a single object to catch the data, the built-in exceptions convert the information into string format and place the string into the reference pointed to by the variable. If you want to catch specific information, as in the preceding example, you need to supply a tuple. The exact format for the returned information is defined by each exception. (See the “Built-in Exceptions” section later in this chapter for more information on the data returned by the standard exceptions.)
The other alternative to the try…except…else statement is the try…finally statement. The format for this version of the try statement is:
try: BLOCK finally: BLOCK
The rules for executing the try… Finally statement are follows:
1.The statement in the try BLOCK are excecuted.
2. If an exception occurs, the finally BLOCK is excecuted before the exception is propagated up to the next level.
3.If no exception occurs, the finally BLOCK is excecuted and control continues abnormal until after the entire try statement.
The try… finally statement is useful in those situations where you want to run a piece of code, irrespective of whether an exception occurs. For example , when communicating with a remote server over a network, you want to trap an error but where EXCEPTION is the name of the exception you want to raise, and DATA is the additional data you want to supply back to the exception handler.
The EXCEPTION can either be one of the built-in exceptions, or you can use an exception or exception class that you have already defined (see “Rolling Your Own Exceptions later in this chapter). The DATA is passed to the exception handler as normal.
The assert Statement
Shorthand for a raise statement, the assert statement works in a similar fashion to the ASSERTO macro in C/C. The assert statement works like a raise statement, but the exception is only raised if the interpreter has not optimized the code (ie, the user has not specified the -O optimization flag). The general format for the assert statement is
assert TEST, DATA
which is essentially equivalent to
if__debug__: if not TEST: raise AssertionError, DATA
Note that the _debug_ symbol is not available when the interpreter is optimizing the code.
This post has become quite big, I will tell in the next post that , Built-in Exceptions, Rolling Your Own Exceptions, etc. in python. How do they work and how do you use them?
Note:- How did you like this post, do tell by commenting below.