1. In Python, there is a distinction between two kinds of errors:
- syntax errors (parsing errors), which occur when the parser comes across a statement that is incorrect. For example:
Trying to execute the following line:1print("Hello, World!)will cause a SyntaxError, and result in the following (or similar) message being displayed in the console:
12345File "main.py", line 1print("Hello, World!)SyntaxError: EOL while scanning string literalPay attention to the arrow – it indicates the place where the Python parser has run into trouble. In our case, it’s the missing double quote. Did you notice it?
- exceptions, which occur even when a statement/expression is syntactically correct; these are the errors that are detected during execution when your code results in an error which is not uncoditionally fatal. For example:
Trying to execute the following line:1print(1/0)
will cause a ZeroDivisionError exception, and result in the following (or similar) message being displayed in the console:1234Traceback (most recent call last):File "main.py", line 1, inprint(1/0)ZeroDivisionError: division by zeroPay attention to the last line of the error message – it actually tells you what happened. There are many different types of exceptions, such as ZeroDivisionError, NameError, TypeError, and many more; and this part of the message informs you of what type of exception has been raised. The preceding lines show you the context in which the exception has occured.
2. You can “catch” and handle exceptions in Python by using the try-except block. So, if you have a suspicion that any particular snippet may raise an exception, you can write the code that will gracefully handle it, and will not interrupt the program. Look at the example:
1 2 3 4 5 6 7 |
while True: try: number = int(input("Enter an integer number: ")) print(number/2) break except: print("Warning: the value entered is not a valid number. Try again...") |
The code above asks the user for input until they enter a valid integer number. If the user enters a value that cannot be converted to an int, the program will print
Warning: the value entered is not a valid number. Try again...
, and ask the user to enter a number again. What happens in such a case?
- The program enters the while loop.
- The
try
block/clause is executed. The user enters a wrong value, for example:hello!
. - An exception occurs, and the rest of the
try
clause is skipped. The program jumps to theexcept
block, executes it, and then continues running after the try-except block.
If the user enters a correct value and no exception occurs, the subsequent instructions in the try block are executed.
1 2 3 4 5 6 7 8 9 10 11 |
while True: try: number = int(input("Enter an int number: ")) print(5/number) break except ValueError: print("Wrong value.") except ZeroDivisionError: print("Sorry. I cannot divide by zero.") except: print("I don't know what to do...") |
You can use multiple except blocks within one try statement, and specify particular exception names. If one of the
except
branches is executed, the other branches will be skipped. Remember: you can specify a particular built-in exception only once. Also, don’t forget that the default (or generic) exception, that is the one with no name specified, should be placed at the bottom of the branch (use the more specific exceptions first, and the more general last).
You can also specify and handle multiple built-in exceptions within a single except clause:
1 2 3 4 5 6 7 8 9 |
while True: try: number = int(input("Enter an int number: ")) print(5/number) break except (ValueError, ZeroDivisionError): print("Wrong value or No division by zero rule broken.") except: print("Sorry, something went wrong...") |
4. Some of the most useful Python built-in exceptions are: ZeroDivisionError, ValueError, TypeError, AttributeError, and SyntaxError. One more exception that, in our opinion, deserves your attention is the KeyboardInterrupt exception, which is raised when the user hits the interrupt key (CTRL-C or Delete). Run the code above and hit the key combination to see what happens.
To learn more about the Python built-in exceptions, consult the official Python documentation.
5. Last but not least, you should remember about testing and debugging your code. Use such debugging techniques as print debugging; if possible – ask someone to read your code and help you to find bugs in it or to improve it; try to isolate the fragment of code that is problematic and susceptible to errors: test your functions by applying predictable argument values, and try to handle the situations when someone enters wrong values; comment out the parts of the code that obscure the issue. Finally, take breaks and come back to your code after some time with a fresh pair of eyes.
Some useful exceptions
Let’s discuss in more detail some useful (or rather, the most common) exceptions you may experience.
ZeroDivisionError
This appears when you try to force Python to perform any operation which provokes division in which the divider is zero, or is indistinguishable from zero. Note that there is more than one Python operator which may cause this exception to raise. Can you guess them all?
Yes, they are: /
, //
, and %
.
ValueError
Expect this exception when you’re dealing with values which may be inappropriately used in some context. In general, this exception is raised when a function (like int()
or float()
) receives an argument of a proper type, but its value is unacceptable.
TypeError
This exception shows up when you try to apply a data whose type cannot be accepted in the current context. Look at the example:
1 2 |
short_list = [1] one_value = short_list[0.5] |
You’re not allowed to use a float value as a list index (the same rule applies to tuples, too).
TypeError
is an adequate name to describe the problem, and an adequate exception to raise.
AttributeError
This exception arrives – among other occasions – when you try to activate a method which doesn’t exist in an item you’re dealing with. For example:
1 2 3 |
short_list = [1] short_list.append(2) short_list.depend(3) |
The third line of our example attempts to make use of a method which isn’t contained in the lists. This is the place where
AttributeError
is raised.
SyntaxError
This exception is raised when the control reaches a line of code which violates Python’s grammar. It may sound strange, but some errors of this kind cannot be identified without first running the code. This kind of behavior is typical of interpreted languages – the interpreter always works in a hurry and has no time to scan the whole source code. It is content with checking the code which is currently being run. An example of such a category of issues will be presented very soon.
It’s a bad idea to handle this exception in your programs. You should produce code that is free of syntax errors, instead of masking the faults you’ve caused.
Exercise 1
What is the output of the following program if the user enters 0
?
1 2 3 4 5 6 7 8 9 |
try: value = int(input("Enter a value: ")) print(value/value) except ValueError: print("Bad input...") except ZeroDivisionError: print("Very bad input...") except: print("Booo!") |
The program will output: Very bad input...
.
Ex. 2
Assuming the user enters 2 as input, what is the output of the following code snippet?
1 2 |
x = input("Enter a number: ") print(x / 0) |
The code will raise a TypeError
exception
- The correct answer is
TypeError
. ATypeError
exception is raised whenever an operation is performed on an incorrect data type. In our example, theinput
function assigns the value2
, entered by the user, into the variablex
, as a string:x = '2'
.
- When evaluating the next
print
statement, the Python interpreter will raise aTypeError
exception, since the division operator does not support string-type operands. In this case, the interpreter raises theTypeError
exception before theZeroDivisionError
exception:print('2' / 0)
->TypeError
.
Ex. 3
What is the output of the following code snippet?
Ex. 4
What is the output of the following code snippet?
1 2 |
for i in range(0, 5, 0): print(i) |
Ex. 6
What is the output of the following code snippet?
1 2 3 4 |
s = "python" s[0] = 'P' print(s) |
A TypeError
exception
Ex. 7
Which of the following code snippets causes a SyntaxError
exception?
Ex. 8
What is the output of the following code snippet?
1 2 |
tpl = (1, 2, 3, 4) tpl.append(5) |
The code will raise the ValueError exception
A SyntaxError
exception