In Python, exceptions are arranged in an inheritance hierarchy
IndexError
for out-of-bounds indexingIndexError
: raised when integer index is out of rangenums = [1, 2, 4]
nums[4] #=> raises IndexError
ValueError
: raised when object is of correct type but has inappropriate valueint("jim") #=> raises ValueError
KeyError
: raised for lookup in a mapping failscodes = dict(gb=44, us=1, no=47, fr=33, es=34)
codes['de'] #=> raises KeyError
mro
:# in repl
>>> IndexError.mro()
#=> [<class 'IndexError'>, <class 'LookupError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>]
>>> KeyError.mro()
#=> [<class 'KeyError'>, <class 'LookupError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>]
args
attributedef boomboom(matchstick):
return matchstick[0]
try:
boomboom(1)
except LookupError as e:
print("boomboom exploded:", e.args)
def main():
try:
b'\x81'.decode('utf-8')
except UnicodeError as e:
print(e)
print("encoding:", e.encoding)
print("reason:", e.reason)
print("object:", e.object)
print("start:", e.start)
print("end:", e.end)
if __name__ == '__main__':
main()
Exception
(not BaseException
)__init__
, __str__
, and __repr__
to provide better outputimport math
class MinimalCustomException(Exception):
pass
class TriangleError(Exception):
def __init__(self, text, sides):
super().__init__(text)
self._sides = tuple(sides)
@property
def sides(self):
return self._sides
def __str__(self):
return "'{}' for sides {}".format(self.args[0], self._sides)
def __repr__(self):
return "TriangleError({!r}, {!r})".format(self.args[0], self._sides)
def triangle_area(a, b, c):
sides = sorted((a, b, c))
if sides[2] > sides[0] + sides[1]:
raise TriangleError("Illegal triangle", sides)
perimeter = (a + b + c) / 2
area = math.sqrt(perimeter * (perimeter - a) * (perimeter - b) * (perimeter - c))
return area
__context__
attribute of most recent exception__cause__
attribute of most recent exceptionimport io
import math
import sys
class MinimalCustomException(Exception):
pass
class TriangleError(Exception):
def __init__(self, text, sides):
super().__init__(text)
self._sides = tuple(sides)
@property
def sides(self):
return self._sides
def __str__(self):
return "'{}' for sides {}".format(self.args[0], self._sides)
def __repr__(self):
return "TriangleError({!r}, {!r})".format(self.args[0], self._sides)
def triangle_area(a, b, c):
sides = sorted((a, b, c))
if sides[2] > sides[0] + sides[1]:
raise TriangleError("Illegal triangle", sides)
perimeter = (a + b + c) / 2
area = math.sqrt(perimeter * (perimeter - a) * (perimeter - b) * (perimeter - c))
return area
def main():
try:
a = triangle_area(3, 4, 10)
print(a)
except TriangleError as e:
try:
print(e, file=sys.stdin)
except io.UnsupportedOperation as f:
print(e)
print(f)
print(f.__context__ is e)
if __name__ == '__main__':
main()
import math
class InclinationError(Exception):
pass
def inclination(dx, dy):
try:
return math.degrees(math.atan(dy / dx))
except ZeroDivisionError as e:
raise InclinationError("Slope cannot be vertical") from e # NOTE: this associates new exception with original exception
if __name__ == '__main__':
try:
inclination(0, 5)
except InclinationError as e:
print(e) #=> Slope cannot be vertical
print(e.__cause__) #=> division by zero
__traceback__
special attribute which contains reference to traceback object associated with
exceptiontraceback
module from Python standard library when working with traceback objectsCAUTION:
__traceback__
beyond scope of except blockimport math
import traceback
class InclinationError(Exception):
pass
def inclination(dx, dy):
try:
return math.degrees(math.atan(dy / dx))
except ZeroDivisionError as e:
raise InclinationError("Slope cannot be vertical") from e # NOTE: this associates new exception with original exception
def main():
try:
inclination(0, 5)
except InclinationError as e:
print(e) #=> Slope cannot be vertical
print(e.__cause__) #=> division by zero
print(e.__traceback__) #=> <traceback object at 0x1018066c8>
traceback.print_tb(e.__traceback__)
s = traceback.format_tb(e.__traceback__) # for rendering
if __name__ == '__main__':
main()
print("Finished")