Sometimes, computer programs behave in non-standard ways.
An exception is a built-in mechanism in a programming language to declare and respond to "exceptional" conditions.
A program raises an exception when an error occurs.
If the exception is not handled, the program will stop running entirely.
But if a programmer can anticipate when exceptions might happen, they can include code for handling the exception, so that the program continues running.
Many languages include exception handling: C++, Java, Python, JavaScript, C#, etc.
Python raises an exception whenever a runtime error occurs.
How an unhandled exception is reported:
>>> 10/0
Traceback (most recent call last):
File "<stdin>", line 1, in
ZeroDivisionError: division by zero
If an exception is not handled, the program stops executing immediately.
A few exception types and examples of buggy code:
Exception | Example | ||||
---|---|---|---|---|---|
OverflowError
| pow(2.12, 1000)
| ||||
TypeError
| 'hello'[1] = 'j'
| ||||
IndexError
| 'hello'[7]
|
See full list in the exceptions docs.
To handle an exception (keep the program running), use a try
statement.
try:
<try suite>
except <exception class> as <name>:
<except suite>
...
The <try suite>
is executed first.
If, during the course of executing the <try suite>
, an exception is raised that is not handled otherwise, and
If the class of the exception inherits from <exception class>
, then
the <except suite>
is executed, with <name>
bound to the exception.
try:
quot = 10/0
except ZeroDivisionError as e:
print('handling a', type(e))
quot = 0
def div_numbers(dividend, divisor):
try:
quotient = dividend/divisor
except ZeroDivisionError:
print("Function was called with 0 as divisor")
quotient = 0
return quotient
div_numbers(10, 2)
div_numbers(10, 0)
div_numbers(10, -1)
def invert(x):
inverse = 1/x # Raises a ZeroDivisionError if x is 0
print('Never printed if x is 0')
return inverse
def invert_safe(x):
try:
return invert(x)
except ZeroDivisionError as e:
print('Handled', e)
return 0
invert_safe(1/0)
try:
invert_safe(0)
except ZeroDivisionError as e:
print('Handled!')
inverrrrt_safe(1/0)
Assert statements raise an exception of type AssertionError
:
assert <expression>, <string>
Assertions are designed to be used liberally. They can be ignored to increase efficiency by running Python with the "-O" flag; "O" stands for optimized.
python3 -O
Any type of exception can be raised with a raise
statement
raise <expression>
<expression> must evaluate to a subclass of BaseException
or an instance of one
Exceptions are constructed like any other object. E.g., TypeError('Bad argument!')
def reduce(f, s, initial):
"""Combine elements of s pairwise using f, starting with initial.
E.g., reduce(mul, [2, 4, 8], 1) is equivalent to mul(mul(mul(1, 2), 4), 8).
>>> reduce(mul, [2, 4, 8], 1)
64
"""
f
: a two-argument function
s
: a sequence of values that can be the second argument
initial
: a value that can be the first argument
def reduce(f, s, initial):
"""Combine elements of s pairwise using f, starting with initial.
>>> reduce(mul, [2, 4, 8], 1)
64
"""
if not s:
return initial
else:
first, rest = s[0], s[1:]
return reduce(f, rest, f(initial, first))
f
: a two-argument function
s
: a sequence of values that can be the second argument
initial
: a value that can be the first argument
def reduce(f, s, initial):
"""Combine elements of s pairwise using f, starting with initial.
>>> reduce(mul, [2, 4, 8], 1)
64
>>> reduce2(pow, [1, 2, 3, 4], 2)
16777216
"""
for x in s:
initial = f(initial, x)
return initial
f
: a two-argument function
s
: a sequence of values that can be the second argument
initial
: a value that can be the first argument
def divide_all(n, ds):
"""Divide n by every d in ds.
>>> divide_all(1024, [2, 4, 8])
16.0
>>> divide_all(1024, [2, 4, 0, 8])
inf
"""
Use the reduce()
function we just defined...
def divide_all(n, ds):
"""Divide n by every d in ds.
>>> divide_all(1024, [2, 4, 8])
16.0
>>> divide_all(1024, [2, 4, 0, 8])
inf
"""
try:
return reduce(truediv, ds, n)
except ZeroDivisionError:
return float('inf')
Using the reduce()
function we just defined.