Sometimes you need to place one exception-handling routine within another in a process called nesting. When you nest exception-handling routines, Python tries to find an exception handler in the nested level first and then moves to the outer layers. You can nest exception-handling routines as deeply as needed to make your code safe.
One of the more common reasons to use a dual layer of exception-handling code is when you want to obtain input from a user and need to place the input code in a loop to ensure that you actually get the required information. The following steps demonstrate how this sort of code might work.
Open a Python File window.
You see an editor in which you can type the example code.
Type the following code into the window — pressing Enter after each line:
TryAgain = True while TryAgain: try: Value = int(input("Type a whole number. ")) except ValueError: print("You must type a whole number!") try: DoOver = input("Try again (y/n)? ") except: print("OK, see you next time!") TryAgain = False else: if (str.upper(DoOver) == "N"): TryAgain = False except KeyboardInterrupt: print("You pressed Ctrl+C!") print("See you next time!") TryAgain = False else: print(Value) TryAgain = False
The code begins by creating an input loop. Using loops for this type of purpose is actually quite common in applications because you don’t want the application to end every time an input error is made. This is a simplified loop, and normally you create a separate function to hold the code.
When the loop starts, the application asks the user to type a whole number. It can be any integer value. If the user types any non-integer value or presses Ctrl+C, Cmd+C, or another interrupt key combination, the exception-handling code takes over. Otherwise, the application prints the value that the user supplied and sets TryAgain to False, which causes the loop to end.
A ValueError exception can occur when the user makes a mistake. Because you don’t know why the user input the wrong value, you have to ask if the user wants to try again. Of course, getting more input from the user could generate another exception. The inner try … except code block handles this secondary input.
Notice the use of the str.upper() function when getting character input from the user. This function makes it possible to receive y or Y as input and accept them both. Whenever you ask the user for character input, it’s a good idea to convert lowercase characters to uppercase so that you can perform a single comparison (reducing the potential for error).
The KeyboardInterrupt exception displays two messages and then exits automatically by setting TryAgain to False. The KeyboardInterrupt occurs only when the user presses a specific key combination designed to end the application. The user is unlikely to want to continue using the application at this point.
Choose Run→Run Module.
You see a Python Shell window open. The application asks the user to input a whole number.
Type Hello and press Enter.
The application displays an error message and asks whether you want to try again.
Type Y and press Enter.
The application asks you to input a whole number again.
Type 5.5 and press Enter.
The application again displays the error message and asks whether you want to try again.
Press Ctrl+C, Cmd+C, or another key combination to interrupt the application.
The application ends. Notice that the message is the one from the inner exception. The application never gets to the outer exception because the inner exception handler provides generic exception handling.
Choose Run→Run Module.
You see a Python Shell window open. The application asks the user to input a whole number.
Press Ctrl+C, Cmd+C, or another key combination to interrupt the application.
The application ends. Notice that the message is the one from the outer exception. In the preious steps, the user ends the application by pressing an interrupt key. However, the application uses two different exception handlers to address the problem.