-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathitem_14.py
executable file
·97 lines (72 loc) · 2.29 KB
/
item_14.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env python3
'''Item 14 from Effective Python'''
# Example 1
'''In the case of dividing by zero, returning None seems natural because the
result is undefined '''
print('Example 1:\n==========')
def divide(a, b):
try:
return a / b
except ZeroDivisionError:
return None
# Example 2
''' Code using this function can interpret the return value accordingly. '''
print('\nExample 2:\n==========')
x, y = 6, 0
result = divide(x, y)
if result is None:
print('Invalid inputs')
# Example 3
''' You may accidentally look for any False equivalent value to indicate errors
instead of only looking for None '''
print('\nExample 3:\n==========')
x, y = 0, 5
result = divide(x, y)
if not result:
print('Invalid inputs') # This is wrong!
# Example 4
''' The first part of the tuple indicates that the operation was a success or
failure.The second part is the actual result that was computed '''
print('\nExample 4:\n==========')
def divide(a, b):
try:
return True, a / b
except ZeroDivisionError:
return False, None
# Example 5
''' Callers of this function have to unpack the tuple. That forces them to
consider the status part of the tuple instead of just looking at the result of
division '''
print('\nExample 5:\n==========')
success, result = divide(x, y)
if not success:
print('Invalid inputs')
# Example 6
''' The problem is that callers can easily ignore the first part of the tuple
(using the underscore variable name, a Python convention for unused variables).
The resulting code doesn't look wrong at first glance. This is as bad as just
returning None '''
print('\nExample 6:\n==========')
_, result = divide(x, y)
if not result:
print('Invalid inputs')
# Example 7
''' The second, better way to reduce these errors is to never return None at
all. Instead, raise an exception up to the caller and make them deal with it
'''
print('\nExample 7:\n==========')
def divide(a, b):
try:
return a / b
except ZeroDivisionError as e:
raise ValueError('Invalid inputs') from e
# Example 8
''' Now the caller should handle the exception for the invalid input case '''
print('\nExample 8:\n==========')
x, y, = 5, 2
try:
result = divide(x, y)
except ValueError:
print('Invalid inputs')
else:
print('Result is %.1f' % result)