Exception
Handle Exception
try:
clause
except ExceptI as errorInfo:
if ExceptI is raised, execute this block
except ExceptII as errorInfo:
if ExceptII is raised, execute this block
except:
handle any other exception
else:
if no exception, execute this block
finally:
this would always be executed
try:
fh = open("testfile", "r")
fh.write("This is my test file for exception handling!!")
except IOError as argument:
print ("Error: can\'t find file or read data", argument)
else:
print ("Written content in the file successfully")
fh.close()
finally:
print("End of try ... except ...")
try:
fh = open("testfile", "r")
raise ValueError('Value Error')
except IOError as argument:
print ("Error: can\'t find file or read data\n", argument)
except Exception as err: # handle any exceptions
print(err)
#except: # handle any exceptions
#print ("Error: value error\n")
else:
print ("Written content in the file successfully")
fh.close()
finally:
print("End of try ... except ...")
Raise Exception
raise Exception(errorInfo)
Python Exception Hierarchy
Raise and Handle
def div(a, b):
if b == 0:
raise ZeroDivisionError("Denominator is zero ...")
return a/b
if __name__ == '__main__':
try:
div(1, 0)
except Exception as err:
print(err.args, err)
def div(a, b):
assert b != 0, 'AssertionError: Divided by zero ...'
return a/b
def main():
try:
div(1, 0)
except Exception as err:
print('Catch error in main ...')
raise # relay exception
if __name__ == '__main__':
try:
main()
except Exception as err:
print(err.args, err)
assert
If the expression is false, Python raises an AssertionError exception
def div(a, b):
assert b != 0, 'AssertionError: Divided by zero ...'
return a/b
if __name__ == '__main__':
try:
div(1, 0)
except Exception as err:
print(err.args, err)
python -O Exception.py, turn off assertion
# Exception.py
def getString():
return "Hello World!"
if __name__ == '__main__':
s = getString()
assert s == "Hello", "string is not correct ..."
print(s) # Hello World!
Traceback
import traceback
def div(a, b):
assert b != 0, 'AssertionError: Divided by zero ...'
return a/b
if __name__ == '__main__':
try:
div(1, 0)
except Exception as err:
print(err.args, err)
traceback.print_exc()
User-Defined Exceptions
class definedExcept(Exception):
def __int__(self, arg):
self.args = arg
def div(a, b):
if b == 0:
raise definedExcept("Defined Exception ...")
return a/b
if __name__ == '__main__':
try:
div(1, 0)
except Exception as err:
print(err.args, err)
Exception Relay
If a function receive an Exception from its sub-function and has no exception handler, the exception is relay to its parent function
def f():
raise Exception('Error in f ...')
def f2():
print('Start f2 ...')
f()
print('Content in f2 ...')
try:
f2()
except Exception as err:
print(err)
# Error in f ...
NotImplemented
If NotImplemented is returned, a reflection will be called
Should be returned by the binary special methods, e.g. __eq__(), __lt__(), __add__()
__radd__ is the reflection function of __add__, it will be used when left object has no __add__ or return NoImplemented
class MyAge(object):
def __init__(self, n):
self.n = n
def __add__(self, other):
if not isinstance(other, MyAge):
print('Return NotImplemented')
return NotImplemented
self.n =self.n + other.n
def __str__(self):
return 'Age: %d' % self.n
class MyCar(object):
def __init__(self, year):
self.year = year
def __radd__(self, other):
print('Call reflection ...')
self.year = self.year + other.n
def __str__(self):
return 'Year: %d' % self.year
a1 = MyAge(42)
a2 = MyAge(41)
a1+a2 # use __add__ of a1
print(a1) # 83
c1 = MyCar(10)
a1 + c1 # use __radd__ of c1 since a1 return NoImplemented
print(a1, c1) # 83, 93
__eq__ is the reflection function of another __eq__, no __req__
== call __eq__ of left object, then call __eq__ of right object if NoImplemented is returned
class MyAge:
def __init__(self, n):
self.n = n
def __eq__(self, other):
if not isinstance(other, MyAge):
return NotImplemented
return self.n == other.n
class MyCar(object):
def __init__(self, year):
self.year = year
def __eq__(self, other):
print('Call reflection ...')
return False
def __str__(self):
return 'Year: %d' % self.year
a1 = MyAge(42)
a2 = MyAge(42)
a1 == a2 # __eq__ in MyAge, True
c1 = MyCar(10)
a1 == c1 # __eq__ in MyCar, False
Reference