Syntax errors and exceptions
A syntax error is a mistake in the rules of writing Python, like a missing colon: if x > 5. Python finds it before running and the program does not start.
An exception is an error that happens while the program runs, even though the code is written correctly. For example print(10 / n) is fine when n = 2, but fails when n = 0. When an exception is raised (thrown) and nobody catches it, Python stops the program and prints a traceback.
Common built-in exceptions
ZeroDivisionError: dividing by zero.ValueError: right type but wrong value, likeint('abc').TypeError: wrong type, like'5' + 2.NameError: a name that was never defined.IndexError: list index out of range.KeyError: a dictionary key that does not exist.FileNotFoundError/IOError: a file cannot be opened.ImportError: a module cannot be imported.EOFError: input() reached end of file.OverflowError,IndentationError,SyntaxErrorare also built in.
try and except
try:
n = int(input('Number: '))
print(100 / n)
except ZeroDivisionError:
print('Cannot divide by zero')
except ValueError:
print('Please type digits only')- Code that might fail goes in the try block.
- When an exception happens, the rest of try is skipped and Python looks for a matching except from the top.
- You can list many types in one line:
except (ValueError, TypeError): - A bare
except:catches any exception. Put it last. except ValueError as e:stores the error message ine.
else and finally
The full shape is try โ except โ else โ finally.
- else runs only if the try block had no exception.
- finally runs always: after success, after a caught error, even if the error was not caught. Use it to close files or free resources.
try:
f = open('marks.txt')
except FileNotFoundError:
print('File missing')
else:
print(f.read())
f.close()
finally:
print('Done')
Raising an exception yourself
raise throws an exception on purpose when the data is wrong.
age = int(input('Age: '))
if age < 0:
raise ValueError('Age cannot be negative')assert is a quick check: assert age >= 0, 'bad age' raises AssertionError if the condition is False.
Try it: break your own program
Write a small program that asks for two numbers and divides them. Run it and type 0, then type 'abc'. Note the name of each exception in the traceback. Now wrap the code in try with one except for each, add a finally that prints 'Thank you', and run the same inputs again. Use the free-play step in the 3D to predict which blocks will run.
Key formulas and definitions
- try: risky code except ErrorType: rescue else: runs if no error finally: always runs
- Syntax error: before running ยท Exception: while running
- raise ErrorType('message') throws an exception on purpose
Worked examples
1. Name the exception: (a) int('12a') (b) [1,2][5] (c) {'a':1}['b'] (d) 7/0 (e) print(total) with no total
(a) ValueError (b) IndexError (c) KeyError (d) ZeroDivisionError (e) NameError.
2. Find the output when n = 0: try: print(10/n) except ZeroDivisionError: print('A') else: print('B') finally: print('C')
10/0 raises ZeroDivisionError โ except prints A. else is skipped (there was an error). finally prints C. Output: A C.
3. Same code with n = 5. Output?
10/5 = 2.0 is printed. No error, so else prints B. finally prints C. Output: 2.0 B C.
4. Write code that keeps asking until the user types a valid integer.
while True: try: n = int(input('Enter an integer: ')) break except ValueError: print('Not an integer, try again') print('You typed', n)
5. What is printed? try: L = [1, 2] print(L[3]) print('X') except IndexError: print('Y')
L[3] raises IndexError, so print('X') is skipped. except prints Y. Output: Y.
6. Write a function that raises ValueError if marks are not between 0 and 100, and call it safely.
def check(m): if not 0 <= m <= 100: raise ValueError('Marks out of range') return m try: check(120) except ValueError as e: print('Error:', e) # Output: Error: Marks out of range
Common mistakes
- Calling a syntax error an exception; syntax errors are found before the program runs, so try cannot catch them in the same file.
- Thinking lines after the error inside try still run. They are skipped.
- Putting a bare except: before specific ones; it catches everything first.
- Thinking finally runs only when there is an error. It runs every time.