Exception handling lets your program gracefully manage errors and unexpected situations, instead of crashing abruptly.
Basic exception handling structure:
The core structure of exception handling in Python involves
try,
except,
else, and
finally blocks.
try:
# code that might raise exceptions
except FirstException as e:
# code to handle FirstException
except SecondException as e:
# code to handle SecondException
except Exception as e:
# code to handle any other exception
else:
# code to execute if no exception was raised
finally:
# code to execute no matter what (exception or not)
Basic exception handling example:
def divide(i, j):
try:
d = i / j
except ZeroDivisionError as e:
print(f'ZeroDivisionError: {e}')
return None
except TypeError as e:
print(f'TypeError: {e}')
return None
else:
print(d)
return d
finally:
print('done')
divide(2, 1) # correct division
divide(2, 0) # zero division
divide(2, 'a') # type error
Output:
2.0
done
ZeroDivisionError: division by zero
done
TypeError: unsupported operand type(s) for /: 'int' and 'str'
done
Failing silently:
try:
i = 1 / 0
except ZeroDivisionError:
pass # special statement that tells python to swallow the exception
Custom exception class example:
class CustomZeroDivisionError(ZeroDivisionError):
"""Custom exception for zero division errors."""
def __init__(self, message, dividend=None, divisor=None):
super().__init__(message + f" | dividend:{dividend}, divisor:{divisor}")
try:
raise CustomZeroDivisionError('division by zero', 1, 0)
except CustomZeroDivisionError as e:
print(e)
Output:
division by zero | dividend:1, divisor:0