Python 101 (part 8): An Exceptionally Clever Snake - Passing The Buck (
Page 5 of 9 )
If one exception handler is nested within another, Python typically uses
the one closest to where the exception occurs. To illustrate this, consider
the following code snippet:
#!/usr/bin/python
# nested_handlers.py
def popeye():
try:
olive()
except NameError:
print "Error in popeye"
def olive():
try:
print someUnnamedVar
except NameError:
print "Error in olive"
try:
popeye()
except NameError:
print "Error in main"
In this case, there are three exception handlers defined for the same type
of exception. The outermost one is in the main program body, the next is
within the popeye() function called from the main script, and the third is
within the olive() function called by popeye().
When olive() runs, it generates a "NameError" exception, which is
immediately handled by its own "try" block.
$ nested_handlers.py
Error in olive
However, if olive() didn't have a "try" block, or its "try" block didn't
account for "NameError" exceptions,
#!/usr/bin/python
def popeye():
try:
olive()
except NameError:
print "Error in popeye"
def olive():
print someUnnamedVar
try:
popeye()
except NameError:
print "Error in main"
the exception would be passed up to the previous level, the calling
popeye() function, which would generate
$ nested_handlers.py
Error in popeye
If popeye()'s exception handler didn't have the ability to handle the
exception, the exception would move up even further, to the main body of
the script,
#!/usr/bin/python
def popeye():
try:
olive()
# this wouldn't handle NameError
except IndexError:
print "Error in popeye"
def olive():
print someUnnamedVar
try:
popeye()
except NameError:
print "Error in main"
which would result in
$ nested_handlers.py
Error in main
And if there weren't any handlers capable of resolving the error,
#!/usr/bin/python
def popeye():
olive()
def olive():
print someUnnamedVar
popeye()
the exception would be processed by the default handlers, which would kill
the script and print a stack trace.
Traceback (innermost last):
File "./test.py", line 9, in ?
popeye()
File "./test.py", line 4, in popeye
olive()
File "./test.py", line 7, in olive
print someUnnamedVar
NameError: someUnnamedVar