1. 收集参数
形参带有*或**,实参为参数列表
*(星号)收集多余参数为一个元组(可能为空),不会收集关键字参数;*不放在最后时,后续参数需要使用名称来指定;
>>>def print_params(*params):
... print(params)
...
>>>print_params()
()
>>>print_params('Testing')
('Testing',)
>>>print_params(1, 2, 3)
(1, 2, 3)
>>>print_params_2('Nothing:')
Nothing:
()
>>>print_params_2('Params:', 1, 2, 3)
Params:
(1, 2, 3)
>>>print_params_2('Hmmm...', something=42)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: print_params_2() got an unexpected keyword argument 'something'
>>>def in_the_middle(x, *y, z):
... print(x, y, z)
...
>>>in_the_middle(1, 2, 3, 4, 5, z = 7)
1 (2, 3, 4, 5) 7
>>>in_the_middle(1, 2, 3, 4, 5, 7)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: in_the_middle() missing 1 required keyword-only argument: 'z'
**(两个星号)收集多余关键字参数为一个字典(可能为空);
>>>def print_params_3(**params):
... print(params)
...
>>>print_params_3(x=1, y=2, z=3)
{'x': 1, 'y': 2, 'z': 3}
>>>def print_params_4(x, y, z=3, *pospar, **keypar):
... print(x, y, z)
... print(pospar)
... print(keypar)
...
>>>print_params_4(1, 2, 3, 5, 6, 7, foo=1, bar=2)
1 2 3
(5, 6, 7)
{'foo': 1, 'bar': 2}
>>>print_params_4(1, 2)
1 2 3
()
{}
对于6.4 2中的存储查询姓名的例子做多个姓名同时插入的改进:
def store(data, *full_names):
for full_name in full_names:
names = full_name.split()
if len(names) == 2: names.insert(1, '')
labels = 'first', 'middle', 'last'
for label, name in zip(labels, names):
people = lookup(data, label, name)
if people:
people.append(full_name)
else:
data[label][name] = [full_name]
2. 分配参数
形参为参数列表,实参带有*或**
>>>def add(x, y):
... return x + y
>>>params = (1, 2)
>>>add(*params)
3
>>>def hello_3(greeting='Hello', name='world'):
... print('{}, {}!'.format(greeting, name))
...
>>>params = {'name':'Sir Robin', 'greeting':'Well met'}
>>>hello_3(**params)
Well met, Sir Robin!
收集参数形参带有*或**,实参为参数列表
分配参数形参为参数列表,实参带有*或**
若形参实参均使用*或**,则只能传递元组或字典,还不如不使用,例子:
>>>def with_stars(**kwds):
... print(kwds['name'], 'is', kwds['age'], 'years old')
...
>>>def without_stars(kwds):
... print(kwds['name'], 'is', kwds['age'], 'years old')
...
>>>args = {'name':'Mr. Gumby', 'age':42}
>>>with_stars(**args)
Mr. Gumby is 42 years old
>>>without_stars(args)
Mr. Gumby is 42 years old
收集和分配参数总例:
>>>def story(**kwds):
... return 'Once upon a time, there was a {job} called {name}.'.format_map(kwds)
>>>print(story(job='king', name='Gumby'))
Once upon a time, there was a king called Gumby.
>>>print(story(name='Sir Robin', job='brave knight'))
Once upon a time, there was a brave knight called Sir Robin.
>>>params = {'job':'language', 'name':'Python'}
>>>print(story(**params))
Once upon a time, there was a language called Python.
>>>print(story(job='aaa',**params))
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: story() got multiple values for keyword argument 'job'
>>>del params['job']
>>>print(story(job='stroke of genius',**params))
Once upon a time, there was a stroke of genius called Python.
>>>def power(x, y, *others):
... if others:
... print('Received redundant parameters:', others)
... return pow(x, y)
>>>power(2, 3)
8
>>>power(3, 2)
9
>>>power(y=3, x=2)
8
>>>params = (5,) * 2
>>>power(*params)
3125
>>>power(3, 3, 'Hello, world')
Received redundant parameters: ('Hello, world',)
27
>>>def interval(start, stop=None, step=1):
... 'Imitates range() for step > 0'
... if stop is None:
... start, stop = 0, start
... result = []
...
... i = start
... while i < stop:
... result.append(i)
... i += step
... return result
>>>interval(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>interval(1, 5)
[1, 2, 3, 4]
>>>interval(3, 12, 4)
[3, 7, 11]
>>>interval(3, 7)
[3, 4, 5, 6]
>>>power(*interval(3, 7))
Received redundant parameters: (5, 6)
81
字典,因为依据Python官方文档的说法这样做的结果是不确定的,即可能得不到想要的结果。