55284A - Introduction To Python - Chapter8
55284A - Introduction To Python - Chapter8
Topics Covered
Th
is
do
cu
Once married, meit would be infinitely easier to ask her father’s forgiveness, than to beg his permission
nt
beforehand. be
lon
No
– A Professional
ja gta gsMrs.
Rider, to Edward Kennard
un p NI
au nilka L
tho nt@ KAN
riz re TE
ed SH
co diff.c WA
pie
Introduction sa
llo
o m R
JA
we GT
d! AP
.
By this time, you’ve probably run into some exceptions (errors) in your Python scripts. In this lesson, we will learn
how to anticipate and handle exceptions gracefully.
Exception Basics
Th
is
do
cu
me
You may remember from nt school that you cannot divide by zero. Two or three people can share a pizza. One person
be
can eat a whole pizza alone. lonBut zero people cannot eat a pizza. The pizza will never get eaten. In Python, if you
No agta gs to
j
un willpnget
try to divide by zero, you il
a ZeroDivisionError
NI exception:
au LK
tho kant A NT
riz @
ed re ES
co diff.c H
pie om WAR
>>> 1/0 s all JA
ow GT
e d AP
Traceback (most recent call last): ! .
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
In some cases,
Th you may be fine with allowing the Python interpreter to report these exceptions as it finds them. But
is
do will want to anticipate and catch these exceptions and handle them in some special way. You do
in other cases, you cu
me
this in Python with try/except
nt blocks. Here’s a very simple example:
be
lon
No jagta gs to
un p
Demo 61: exception-handling/Demos/[Link]
au nilka L
tho nt@ KAN
riz r e TE
ed SH
co diff.c
1. try: pie om WAR
sa JA
2. 1/0 llo GT
we AP
d! .
3. except:
4. print('You cannot divide by zero!')
Th
Multiple except
is Clauses
do
cu
You can have multiple meexcept clauses with each clause specifying the type of exception to catch:
nt
be
lon
N ja g gs
Demo 62: exception-handling/Demos/[Link]
1. def divide():
2. try:
3. numerator = int(input('Enter a numerator: '))
4. denominator = int(input('Enter a denominator: '))
5. result = numerator / denominator
6. print(numerator, 'over', denominator, 'equals', result)
7. except
T ValueError:
his
8. dprint('Integers
oc only please. Try again.')
um
9. e
divide()nt
be
lo
10. jag ngs
exceptN ZeroDivisionError:
ou ta to
na pnilcannot N divide by zero! Try again.')
11. print('You uth kan ILKA
ori t@ NT
divide() ze
d c rediff ESH
12.
op . WA
13. except KeyboardInterrupt: ies com R
a JA
14. print('Quitter!') llow GT
AP
ed
! .
15. except:
16. print('I have no idea what went wrong!')
17.
18. def main():
19. divide()
Th
is
20. do
cu
21. main()
men
tb
elo
n
No agta gs to
j
un pn NI
au il LK
Code Explanation tho kant
riz @ ANT
ed re ES
co diff.c H
p om WAR
1. If the user enters anything otheriesthan all an JAfor the numerator or denominator, the int() function will fail
integer
ow GT
and a ValueError exception will be thrown. ed AP
! .
2. If the user enters 0 for the denominator, a ZeroDivisionError exception will be thrown.
3. If the user quits the program by pressing CTRL+C, a KeyboardInterrupt exception will be thrown.
4. Thexcept clause, which is optional, serves as a wildcard to catch any unspecified exception types.
The last
is
do
cu
me
nt
be
lon
Run the program and tryja entering different values to see how it works.
No gta gs to
un pn NI
au il LK
tho kant
riz @ ANT
ed re ES
co diffpython H [Link]
om WAR
PS …\exception-handling\Demos> . c
pie
Integers only please. Try [Link] s JA
ow GT
ed AP
Enter a numerator: 10 ! .
Enter a denominator: 0
You cannot divide by zero! Try again.
Enter a numerator: 10
Enter a denominator: 2
10 over 2 Tequals
his 5.0
do
cu
m
PS …\exception-handling\Demos>
en
python [Link]
Enter a numerator: 5belo
t
N jag ngs
Enter a denominator: Quitter!
At the end, the user pressed Ctrl+C to end the program.
Including a wildcard except clause can be dangerous because it can hide a real error. If you do use it, you may
Th
want to print a ifriendly
sd
oc error message and then reraise the error, like this:
um
en
tb
elo
Demo 63: exception-handling/Demos/[Link]
n
No jagta gs to
un p NI
au nilka L
tho nt@ KAN
1. try: riz red TES
ed
2. 1/0
c op [Link] HWA
ies m R
all JA
3. except: ow GT
ed AP
4. print('Something really bad just happened! ! . Oh no, oh no, oh no!')
5. raise
Code Explanation
Th
is
d
This first prints theocfriendly
um error (if you want it to be friendly) and then outputs the interpreter’s traceback:
en
tb
elo
n
No jagta gs to
un pn NI
au just il LK
Something really bad
tho kanhappened!
t AN Oh no, oh no, oh no!
r @ T
Traceback (most recent icall ze r
d c ediff
last): E S
o .co HWA
File ".\[Link]", line 2,piin es m
<module> R
all JA
1/0 ow GT
ed AP
! .
ZeroDivisionError: division by zero
<class 'ZeroDivisionError'>
division by zero
Than arbitrary variable name. You can name the variable whatever you like.
Note that e is is
do
cu
me
nt
be
lon
ExerciseNo 25:gtaRaising
ja gs
pn to NI
Exceptions
un ilka
au LK
tho n A
riz t@re NTE
ed d SH
co if
pie [Link] WAR
15 to 25 minutes sa JA
llo GT
we AP
d! .
In this exercise, you will intentionally try to create different types of exceptions using the following template:
try:
Th
is creates exception
# code thatd oc
u
except Exceptionmas
en e:
tb
print(type(e)) elo
n
No agta gs to
j
print(e, '\n') u
na p n N
uth ilkan ILKA
ori t N
ze @red TES
dc iff HW
op .
ies com AR
all JA
ow GT
ed
1. Open exception-handling/Exercises/exception_details.py AP in your editor.
! .
B. ValueError
Th
is
do
C. NameError cu
me
nt
be
lon
D. FileNotFoundError
No jagta gs to
un p NI
au nilka L
E. ModuleNotFoundError tho nt@ KAN
riz r e TE
ed SH
co diff.c WA
F. TypeError p i es o m R
all JA
ow GT
ed AP
G. AttributeError ! .
H. StopIteration
I. KeyError
3. Use theThdocumentation
is at [Link] [Link]#base-
do
classes as cnecessary.
um
en
tb
elo
ja ng
N g s
Solution: exception-handling/Solutions/exception_details.py
1. # ZeroDivisionError
2. try:
3. 1/0
4. except Exception as e:
5. print(type(e))
T his
6. do
print(e, '\n')
c um
7. en
tb
elo
n
8. # ValueError ja
No gta gs to
un pn
9. try: a ilk NIL
KA uth an
NT ori t@
10. int('a') re dif ESH ze
dc f
11. except Exception as e:opie .com WAR
sa JA
12. print(type(e)) llo GT
we AP
d! .
13. print(e, '\n')
14.
15. # NameError
16. try:
17. print(foo)
Th
18. exceptisException
do as e:
cu
19. me
print(type(e))
n
tb
20.
e
lon
print(e, '\n')
No agta gs to
j
21. un p NI
au nilka LK
22. # FileNotFoundErrort h ori n t@ ANT
ze
d c rediff ESH
23. try: op . WA
ies com R
24. open('[Link]', a llo JA
'r')
we GT
d AP
25. except Exception as e: ! .
26. print(type(e))
27. print(e, '\n')
28.
29. # ImportError
T
30. try: his
do
c
31. importum
non_existing_module
e nt
32. except Exceptionbe as e:
lo
N jag ngs
33. ou tap
print(type(e)) to
na nil NI
ka L
34. uth
print(e, '\n')o nt@ KAN
riz r e TE
ed SH
35. co diff.c
pie om WAR
36. # TypeError sa JA
llo GT
we AP
37. try: d! .
38. nums = [1, 2] # Lists are iterables, not iterators
39. next(nums)
40. except Exception as e:
41. print(type(e))
42. Th
print(e, '\n')
i sd
oc
43. um
en
44. tb
# AttributeError e lon
45. try: N jag gs
46. greeting = 'Hello'
47. [Link]() # strings don't have a print() method
48. except Exception as e:
49. print(type(e))
50. print(e, '\n')
51.
52. # StopIteration
Th
is
53. try: do
u c
54. nums = m en 2]
[1,
tb
55.
elo
iter_nums = iter(nums)
n jag gs
ou apN oNt t
56. print(next(iter_nums))
n n I
ilka au LK
t ho n A
57. riz t@re NTE
print(next(iter_nums))
ed d SH
co if
58. print(next(iter_nums)) pie [Link] WAR
sa JA
59. except Exception as e: llo GT
we AP
60. print(type(e)) d! .
61. print(e, '\n')
62.
63. # KeyError
64. try:
This
65. grades = {'English':97, 'Math':93, 'Art':74, 'Music':86}
do
um c
66. print(grades['Science'])
e nt
67. except Exceptionbe as e:
lon
68. No agta gs to
j
print(type(e))
u p na nil NI
ka L
69. uth
print(e, '\n')o nt@ KAN
riz re TE
ed SH
co diff.c
pie om WAR
sa JA
llo GT
Code Explanation we AP
d! .
<class 'ZeroDivisionError'>
Th
division byiszero
do
cu
men
tb
e
<class 'ValueError'> lon
N ja gta g s
invalid literal ofor p twith
o N base 10: 'a'
un int()
au nilka ILK
AN tho nt@
red TES riz
H ed
co if
<class 'NameError'> pie [Link] WAR
sa JA
name 'foo' is not defined llo GT
we AP
d! .
<class 'FileNotFoundError'>
[Errno 2] No such file or directory: '[Link]'
<class 'ModuleNotFoundError'>
Th
is
No module named 'non_existing_module'
do
cu
men
t
<class 'TypeError'> belo
jag ngs
N not
'list' object is an iterator
<class 'AttributeError'>
'str' object has no attribute 'print'
1
2
<class 'StopIteration'>
Th
is
do
cu
me
<class 'KeyError'> nt
be
'Science' lon
No jagta gs to
un p NI
au nilka L
tho nt@ KAN
riz re TE
ed SH
co diff.c
The else Clause pie om WAR
sa JA
llo GT
we AP
You should limit your try clause to the code dthat . an exception. After the final except clause, you
! might cause
can include an else clause that contains code that only runs if no exception was raised in the try clause. Take a
look at the following example:
Code Explanation
The difference between using if/else and try/except for flow control is the difference between asking for
Th asking for forgiveness.
permission andis
do
cu
me
nt
be
lon
ExerciseNo 26: jag Running
g
tap s to Sum
un NI
au nilka LK
tho n A
riz t@re NTE
ed d SH
co if
pie [Link] WAR
10 to 20 minutes sa JA
llo GT
we AP
d! .
In this exercise, you will change a function that uses an if-else construct to use a try-except construct instead.
1. Open exception-handling/Exercises/running_sum.py in your editor and study the code. The code
repeatedly prompts the user for a number, adding each valid entry to a total. If the user enters “q”, the
Th
program iquits.
s d If they enter any other non-integer value, the function prompts them for integers only. Run the
oc
um
script to see how eitn works.
tb
elo
ja ng
2. Now, replace theN g tap s toblock with a try-except block. The script should continue to work in exactly the
o u if-else
na n N
same way. uth ilkan ILKA
ori t N
ze @red TES
dc iff. HW
op
ies com AR
all JA
ow
Exercise Code: exception-handling/Exercises/running_sum.py GT
ed AP
! .
1. def main():
2. total = 0
3. while True:
4. Th num = input('Enter a number (q to quit): ')
is
do
5. cu
me
nt
6. be
if [Link]() == 'q':
lo
7. jag ngs
N print('Goodbye!')
8. break
9.
10. if not [Link]():
11. print('Integers only please. Try again.')
12. else:
13. total += int(num)
14. print('The current total is:', total)
Th
is
15. do
cu
16. main() men
tb
elo
n
No jagta gs to
un p NI
au nilka L
tho nt@ KAN
riz re TE
Solution: exception-handling/Solutions/running_sum.py
ed SH
co diff.c
pie om WAR
sa JA
llo GT
we AP
1. def main(): d! .
2. total = 0
3. while True:
4. try:
5. num = input('Enter a number: ')
6. Th if [Link]() == 'q':
is
do
7. cu print('Goodbye!')
men
8. t b break
elo
9. j
No numag = nint(num)
gs # This might cause an error
t t
un apni o NI
a l L
10. tho kant
except uValueError: K
riz @ ANT
11. print('Integersed re ES please. Try again.')
only
co diff.c HW
pie o AR
12. else: sa m JA
llo GT
13. total += num we AP
d! .
14. print('The current total is:', total)
15.
16. main()
Th
is
do
Raising Your cOwn
um
e Exceptions
nt
be
lo
Sometimes it can be jag tongraise
Nouseful your own exceptions, which you do with the raise statement. To illustrate,
tap s to
u
consider the following function,
na N
n which creates a bi-directional dictionary from a dictionary:
uth ilkan ILKA
ori t N
ze @red TES
dc iff. HW
op
ies com AR
def bidict(d): all JA
ow GT
ed AP
d2 = [Link]() ! .
for k,v in [Link]():
d2[v] = k
return d2
Th
is
do
If you pass {'hola':'hi',
cu 'adios':'bye'} to this function, it will return this dictionary:
me
nt
be
lon
N ja g gs
{'hola':'hi', 'adios':'bye', 'hi': 'hola', 'bye': 'adios'}
You can use this new dictionary to look up values in either direction. But what if you pass bidict() a dictionary
that has two keys with the same values, like this:
Th
{'hola':'hi',
is 'adios':'bye', 'ciao':'bye'}
do
cu
men
tb
elo
ng the mapping you want, because the bye key can only have one value:
It won’t error, but itNwon’tjagreturn
ou tap s to
na n N
uth ilkan ILKA
ori t@ NT
ze
d c rediff ESH
. WA
op 'ciao':'bye',
{'hola':'hi', 'adios':'bye', ies com R 'hi': 'hola', 'bye': 'adios'}
all JA
ow GT
ed AP
! .
The value of the bye key is 'adios', but there is no key with the value of 'ciao'.
Consider the loop in the bidict() function. Each time it assigns a value to a key. But if that key already exists, it
overwrites the existing value.
Th
is
do
One way to handle cuthis is to raise an exception, like this:
me
nt
be
lon
No agta gs to
j
un p NI
def bidict(d): au nilka L
tho nt@ KAN
r ize T
d c rediff ESH
d2 = [Link]()
op . WA
for k,v in [Link](): ies com R
all JA
if v in [Link](): ow GT
ed AP
! .
raise KeyError('Cannot create bidirectional dict ' +
'with duplicate keys.')
d2[v] = k
return d2
Th
is
do
cu
Now, when a programmer tries to pass a dict that won’t work with the function, it will raise an exception. Here is
me
nt
the full code: be
lon
No jagta gs to
un p NI
au nilka L
Demo 67: exception-handling/Demos/bidict_with_exception.py
tho nt@ KAN
riz r e TE
ed SH
co diff.c
pie om WAR
1. def bidict(d): sa JA
llo GT
we AP
2. d2 = [Link]() d! .
3. for k, v in [Link]():
4. if v in [Link]():
5. raise KeyError('Cannot create bidirectional dict ' +
6. 'with duplicate keys.')
7. Th
is d2[v] = k
do
8. returncum
d2
en
9. tb
elo
ja ng
10. g s
translatorN = bidict({'hola':'hi', 'adios':'bye'})
11. print(translator['hola'])
12. print(translator['hi'])
13.
14. translator2 = bidict({'hola':'hi', 'adios':'bye', 'ciao':'bye'})
Code Explanation
Th
is
do
Run this and you willcu see that the call creating translator works, but the call creating translator2 does not:
me
nt
be
lon
No ja gta gs to
un p NI
au nilka L
hi tho nt@ KAN
riz re TE
hola ed SH
co diff.c WA
Traceback (most recent call plast): ies om R
all JA
o GT
File ".\bidict_with_exception.py",weline 14, in AP<module>
d! .
translator2 = bidict({'hola':'hi', 'adios':'bye', 'ciao':'bye'})
File ".\bidict_with_exception.py", line 5, in bidict
raise KeyError('Cannot create bidirectional dict ' +
KeyError: 'Cannot create bidirectional dict with duplicate keys.'
Th
is
do
cu
men
tb
Conclusion elo
n
No agta gs to
j
u p
In this lesson, you havenalearned n Nhandle
uth ilkato ILK Python exceptions. For further study, see
ori n t@ ANT
ze
d c rediff ESH
op . WA
ies com
[Link] R
all JA
ow GT
ed AP
! .
Th
is
do
cu
men
tb
elo
n
No agta gs to
j
un pn NI
au il LK
tho kant
riz @ ANT
ed re ES
co diff.c HW
pie o AR
sa m JA
llo GT
we AP
d! .
Th
is
do
cu
men
tb
elo
jag ng
N s