What Are Exceptions?
An exception is an unexpected runtime error that causes a program to crash. For example, try entering a value of 0 for the second number when you run this program:
1 2 3 4 5 6 7 |
# Get two numbers. num1 = int(input('Enter a number: ')) num2 = int(input('Enter another number: ')) # Divide num1 by num2 and display the result. result = num1 / num2 print(num1, 'divided by', num2, 'is', result) |
This program will cause a ZeroDivisionError exception to occur if you try to divide by zero (0):
builtins.ZeroDivisionError: division by zero
Input Validation (review)
By now you know that input validation is important in programming, so we could avoid the exception in the first place like this:
1 2 3 4 5 6 7 8 9 10 11 |
# Get two numbers. num1 = int(input('Enter a number: ')) num2 = int(input('Enter another number: ')) # If num2 is not 0, divide num1 by num2 # and display the result. if num2 != 0: result = num1 / num2 print(num1, 'divided by', num2, 'is', result) else: print('Cannot divide by zero.') |
However, sometimes exceptions (especially those involving a human user) cannot be avoided regardless of how carefully you write your program and we need a way to deal with such situations.
Exception Handling
Python, like most modern languages, allows you to write code that responds to exceptions when they are raised and prevents the program from crashing. Such code is called an exception handler and is written using a try/except statement. Here’s the general format in Python:
The block of code following the try keyword is called the try block and contains one or more statements that can potentially raise an exception. After the try block, an except clause appears. The except clause begins with the keyword except, (optionally) followed by the name of an exception, and ending with a colon (:). The block of code that follows this is referred to as the handler.
If a statement in the try block raises an exception that matches ExceptionName, then the handler executes. The program then resumes execution with the statement immediately following the try/except statement. If an exception is raised but does not match ExceptionName, then the program will crash as usual. If the try block executes without an exception occurring, then the code in the handler is skipped completely and execution continues with the statement immediately following the try/except statement.
Let’s fix the previous example using exception handling:
1 2 3 4 5 6 7 8 9 10 |
# Get two numbers. num1 = int(input('Enter a number: ')) num2 = int(input('Enter another number: ')) # Try to divide and deal with a possible ZeroDivisionError exception try: result = num1 / num2 print(num1, 'divided by', num2, 'is', result) except ZeroDivisionError: print('Cannot divide by zero.') |
What’s the difference?
It’s important to distinguish between input validation and exception handling. With input validation, we check that what the user entered is legal before attempting to do anything with it in our program. With exception handling, we assume that what the user entered is legal, attempt to use it, and handle any exceptions that might occur. In other words, rather than avoiding an exception in the first place (input validation), we allow the exception to happen but deal with it gracefully (exception handling).
Exception Handling Tips
When should you check for exceptions? Whenever you are getting input in your program is a good place to think about exceptions.
In some cases, the code within a try block may be capable of raising more than one type of exception. To deal with this situation you can include more than one except clause. It’s good programming practice to be specific about exception types and handle each case individually. In fact, it’s often dangerous to catch all exceptions by using except: as a catchall.
Style Rule #10: Exception HandlingExcept clauses should always explicitly name the exception they are handling. Avoid using an except clause without an exception name as this leaves the purpose of the exception handling code very vague. Also, it’s considered good style to be focused in your exception handling. Don’t put your entire program in one big try block! Only put statements likely to raise an exception within a try block. |
Let’s say you know that you want to check for an exception, but you’re not exactly sure what the exception type is called. The best way to find out is to actually cause the exception to happen, then carefully read the error message from the Python interpreter.
You Try!
-
- Start a new page in your Learning Journal titled “3-3 Exception Handling“. Carefully read the notes above and in your own words summarize the key ideas from each section. Think of it as writing a “cheat sheet” for this lesson. Making these notes will help solidify your understanding of the material and serve as a future reference to help you review key concepts.
- Try to figure out what the following code will display, then check your hypothesis using the Python interpreter.
1234567891011try:x = float("abc123")print(3 / x)except ZeroDivisionError:print("This code caused an ZeroDivisionError")except ValueError:print("This code caused a ValueError")print ("The End.") - Research and write a line of Python code that will cause the following exceptions:
- ZeroDivisionError
- ValueError
- TypeError
- NameError