- SyntaxError: Python can’t parse program
- NameError: local or global name not found
- AttributeError: attribute reference fails
- TypeError: operand doesn’t have correct type
- ValueError: operand type okay, but value is illegal
- IOError: IO system reports malfunction (e.g. file not found)
Handlers for exceptions
try & except
exception rises by any statement in body of try are handled by except statement,
and execution continues after the body of the except statement
try:
a = int(input("Tell me one number:"))
b = int(input("Tell me another number:"))
print(a/b)
print("Okay")
except:
print("Bug in user input.")
print("Outside")
have separate except clauses to deal with a particular type of exception
try:
a = int(input("Tell me one number:"))
b = int(input("Tell me another number:"))
print(a/b)
print("Okay")
except ValueError:
print("Could not convert to a number.")
except ZeroDivisionError
print("balbala...")
print("Outsdie.")
else || finally
- else:
- body of this excuted when execution of associated try body
completes with no exceptions
- body of this excuted when execution of associated try body
- finally:
- body of this is
always excuted
after try, else and except, even if they raised another error or excuted a break, continue or return.
- body of this is
Exception example
data = []
file_name = input("Provide a name of a file of data ")
try:
fh = open(file_name, 'r')
except IOError:
print('cannot open', file_name)
else:
for new in fh:
if new != '\n':
addIt = new[:-1].split(',') #remove trailing \n
data.append(addIt)
finally:
fh.close() # close file even if fail
gradesData = []
if data:
for student in data:
try:
name = student[0:-1]
grades = int(student[-1])
gradesData.append([name, [grades]])
except ValueError:
gradesData.append([student[:], []])
Exceptions as control flow
- raise an exception when unable to produce a result consistent with function’s specification.
- handle error instead of simply stop the excution
def get_ratios(L1, L2):
""" Assumes: L1 and L2 are lists of equal length of numbers
Returns: a list containing L1[i]/L2[i] """
ratios = []
for index in range(len(L1)):
try:
ratios.append(L1[index]/float(L2[index]))
except ZeroDivisionError:
ratios.append(float('NaN')) #NaN = Not a Number
except:
raise ValueError('get_ratios called with bad arg')
# print something when expected error occurs
return ratios
Exercise
def fancy_divide(numbers, index):
try:
denom = numbers[index]
for i in range(len(numbers)):
numbers[i] /= denom
except IndexError:
fancy_divide(numbers, len(numbers) - 1)
except ZeroDivisionError:
print("-2")
else:
print("1")
finally:
print("0")
What does fancy_divide([0, 2, 4], 4)
print out?
1,0,0
THIS LAST 0 COMES FROM HERE
💡 Quick explaination:
- try: do something
- except: do if there was an exception caught while trying (there can be more than one)
- else: do if there is no exception but before finally
- finally: do this, ALWAYS, at the end then any further lines are normal program flow so do something >after finally if no uncaught exception crashed the program
Assertions
def avg(grades):
assert not len(grades) == 0, 'no grades data'
return sum(grades)/len(grades)
Raises an AssertionError if it is given an empty list for grades
💡 Function ends immediately if assertion not meet