At this point, you already know what errors can occur while you work on your code. You might even know how to deal with some of them. But what if you cannot control some parts of your code, like the user input? Moreover, users don't always follow the instructions, so making your way through it is the only way. Don't worry; Python, as always, has your back. In this topic, you'll learn some tools to help with emerging errors.
Suppose you have a simple calculator. It can only divide numbers. Users input two numbers, and then it prints the result.
number_one = int(input("Please, enter the first number: "))
number_two = int(input("Please, enter the second number: "))
result = number_one / number_two
print("The result of your division is: ", result)
Let's run it:
>>> Please, enter the first number: 5
>>> Please, enter the second number: 2
>>> The result of your division is: 2.5
Now let's try the impossible:
>>> Please, enter the first number: 5
>>> Please, enter the second number: 0
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:/Users/User/.PyCharm2018.2/config/scratches/scratch_9.py", line 3, in <module>
result = number_one / number_two
ZeroDivisionError: division by zero
Something is wrong here, and the program crashes! To prevent this, use the try-except statements where you think it may lead to errors. The place where we divide is the result variable. Let's brace it with the try-except blocks:
number_one = int(input("Please, enter the first number: "))
number_two = int(input("Please, enter the second number: "))
try:
result = number_one / number_two
except ZeroDivisionError:
print("We achieve it thanks to except ***You can not divide by zero!!")
else:
print("The result of your division is: ", result)
finally:
print("It is done through finally ***Thanks for using our calculator! Come again!")Exception handling keywords
Here you can see not only try and except keywords but also else and finally. The entire exception handling block works as follows:
First, if there is no exception, Python executes the
tryblock: everything betweentryandexcept;If an exception occurs, the rest of the try block is skipped. After that, Python checks whether the exception type matches the specified exception after the
exceptkeyword. It executes the except block and continues with the program after the try-except block.If an exception doesn't match the specified exception, it is called an unhandled exception. The execution of your program stops with a traceback.
The
elseblock is executed only if there were no exceptions in thetryblock, as though it was a more familiarif-elsestatement. It's better to useelsethan adding code to thetryblock, as you can avoid accidentally catching another exception if you haven't initially planned to catch with thetryblock and be aware of it in time.There can also be the
finallykeyword. Thefinallyclause is always executed before leaving thetry-exceptblock, whether an exception has occurred or not.
So, let's try running our program now!
>>> Please, enter the first number: 5
>>> Please, enter the second number: 0
>>> We achieve it thanks to except ***You can not divide by zero!!
>>> It is done through finally ***Thanks for using our calculator! Come again!
See? Now, your program works even if the user makes a mistake and wants to divide by zero.
Handling several exceptions
But what if the user doesn't understand what the number is and enters, for example, one?
>>> Please, enter the first number: 5
>>> Please, enter the second number: one
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:/Users/User/.PyCharm2018.2/config/scratches/scratch_9.py", line 2, in <module>
number_two = int(input("Please, enter the second number: "))
ValueError: invalid literal for int() with base 10: 'one'
Oh, no! The annoying traceback again! Why? Well, because you specified only the ZeroDivisionError exception in the try-except block. There's also a ValueError exception here, so Python doesn't know how to deal with it in your program.
The built-in exceptions have a hierarchical structure. So, you can do the following and identify no specific exception:
except:
print("An error occurred! Try again.")
This way, you catch any exceptions from the list. But it also works for KeyboardInterrupt and other helpful exceptions. It is a bad practice in programming, so it is better to use two or more except blocks for different exceptions:
except ZeroDivisionError:
print("We achieve it thanks to except ***You can't divide by zero!!")
except ValueError:
print("You can only enter numbers consisting of digits, not text!!")
The except clause also may specify multiple exceptions as a parenthesized tuple, for example:
except (ValueError, TypeError):
print("You can only enter numbers consisting of digits, not text!!")
Due to the hierarchical structure, one exception can catch numerous exceptions:
except ArithmeticError:
print("I will also catch FloatingPointError, OverflowError, and ZeroDivisionError")
Sometimes, you can't even predict the exception type in your code. In this case, you have no choice but to use the most general exception. For that purpose, instead of using pure except: statements
except:
# do something
Use except Exception:
except Exception:
# do something
except Exception contains all Python exceptions except for GeneratorExit, KeyboardInterrupt, SystemExit. So if you use this structure, you can still finish your program by means of a keyboard or commands, which causes SystemExit.
Conclusion
To deal with exceptions without terminating your program, Python has a
try-exceptblock;There are two more blocks to expand the possibilities to change the behavior of a program:
elseexecuted only if there are no exceptions in try-block, andfinallyperformed at the end of the try-except block whether the exception happens or not.All the exceptions comprise a hierarchical structure: some exceptions also include others.
If you want to catch all possible exceptions, use the
except Exceptionconstruction.
Using them wisely will make your code sustainable and effective; you'll prevent many user mistakes and keep your program running even under unexpected circumstances.