Skip to content

Commit f6e08b7

Browse files
committed
Added item_18
1 parent ef93855 commit f6e08b7

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

item_18.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#!/usr/bin/env python3
2+
3+
'''Item 18 from Effective Python'''
4+
5+
6+
# Example 1
7+
''' say you want to log some debug information. With a fixed number of
8+
arguments, you would need a function that takes a message and a list of values
9+
'''
10+
print('Example 1:\n==========')
11+
12+
def log(message, values):
13+
if not values:
14+
print(message)
15+
else:
16+
values_str = ', '.join(str(x) for x in values)
17+
print('%s: %s' % (message, values_str))
18+
19+
log('My numbers are', [1, 2])
20+
log('Hi there', [])
21+
22+
23+
# Example 2
24+
''' The first parameter for the log message is required, whereas any number of
25+
subsequent positional arguments are optional. The function body doesn't need to
26+
change, only the callers do '''
27+
print('\nExample 2:\n==========')
28+
29+
def log(message, *values): # The only difference
30+
if not values:
31+
print(message)
32+
else:
33+
values_str = ', '.join(str(x) for x in values)
34+
print('%s: %s' % (message, values_str))
35+
36+
log('My numbers are', 1 ,2)
37+
log('Hi there') # Much better
38+
39+
40+
# Example 3
41+
''' If you already have a list and want to call a variable argument function
42+
like log , you can do this by using the * operator. This instructs Python to
43+
pass items from the sequence as positional arguments '''
44+
print('\nExample 3:\n==========')
45+
46+
favourites = [7, 33, 99]
47+
log('Favourite colours', *favourites)
48+
49+
50+
# Example 4
51+
''' the variable arguments are always turned into a tuple before they are
52+
passed to your function. This means that if the caller of your function uses
53+
the * operator on a generator, it will be iterated until it's exhausted '''
54+
print('\nExample 4:\n==========')
55+
56+
def my_generator():
57+
for i in range(10):
58+
yield i
59+
60+
61+
def my_func(*args):
62+
print(args)
63+
64+
65+
it = my_generator()
66+
my_func(*it)
67+
68+
69+
# Example 5
70+
''' If you try to add a positional argument in the front of the argument list,
71+
existing callers will subtly break if they aren't updated '''
72+
print('\nExample 5:\n==========')
73+
74+
def log(sequence, message, *values):
75+
if not values:
76+
print('%s: %s' % (sequence, message))
77+
else:
78+
values_str = ', '.join(str(x) for x in values)
79+
print('%s: %s: %s' % (sequence, message, values_str))
80+
81+
82+
log(1, 'Favourites', 7, 33) # New usage is OK
83+
log('Favourite numbers', 7, 33) # Old usage breaks

0 commit comments

Comments
 (0)