附2:使用*收集和分配参数

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官方文档的说法这样做的结果是不确定的,即可能得不到想要的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MallocLu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值