6 minutes read

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 try block: everything between try and except;

  • 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 except keyword. 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 else block is executed only if there were no exceptions in the try block, as though it was a more familiar if-else statement. It's better to use else than adding code to the try block, as you can avoid accidentally catching another exception if you haven't initially planned to catch with the try block and be aware of it in time.

  • There can also be the finally keyword. The finally clause is always executed before leaving the try-except block, whether an exception has occurred or not.

try except

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-except block;

  • There are two more blocks to expand the possibilities to change the behavior of a program: else executed only if there are no exceptions in try-block, and finally performed 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 Exception construction.

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.

684 learners liked this piece of theory. 14 didn't like it. What about you?
Report a typo