python使用中我们经常看到*
和**
,那么这个究竟作用如何。我个人的理解是用在解包和压包。
压包-收集参数
变量赋值
我们将自己的数据集一次收集,假设我们有列表[‘sandwich’, 23, ‘South Street’, ‘banana’]。
name, age, addr, fav = ['sandwich', 23, 'South Street', 'banana']
name, fav
('sandwich', 'banana')
如果我们只需要姓名和年龄,我们可以这么做:
name, age, *_ = ['sandwich', 23, 'South Street', 'banana']
name
'sandwich'
_
['South Street', 'banana']
这里我们就将第3个之后的所有的数据压包了。我们使用其收集参数时,不能有多个*收集,这样无法定位参数:
*_, addr, *__ = ['sandwich', 23, 'South Street', 'banana']
addr
File "<ipython-input-4-914d4b6c27b2>", line 1
*_, addr, *__ = ['sandwich', 23, 'South Street', 'banana']
^
SyntaxError: two starred expressions in assignment
因为这样无法定位addr参数的具体位置,应当如下操作:
*_, addr, ignore = ['sandwich', 23, 'South Street', 'banana']
addr
'South Street'
定义函数
定义函数时,使用*, **来收集参数和收集参数名加参数:
def test(*args, **kwargs):
print(type(args))
print('------------')
print(args)
print(type(kwargs))
print('------------')
print(kwargs)
这个函数没有实际意义,用于展示收集参数的效果。
test(1, 3, 5, a='hello', b='world')
<class 'tuple'>
------------
(1, 3, 5)
<class 'dict'>
------------
{'a': 'hello', 'b': 'world'}
很明显,没有命名的参数都被收集,并用元组存储(没有命名则顺序很重要否则无法定位!所以使用元组),命名参数收集使用字典存储(k:参数名,v:参数值,命名参数顺序不重要所以使用字典)
这样能清楚地定位到参数!
解包-释放参数
这点有点难理解,所有的解包必须作用在表达式参与计算才有意义:
info = ['sandwich', 23] # 基本信息
name, age, addr, fav = (*info, 'South Street', 'banana')
name, fav
('sandwich', 'banana')
调用函数时释放参数
print(str.format.__doc__)
S.format(*args, **kwargs) -> str
Return a formatted version of S, using substitutions from args and kwargs.
The substitutions are identified by braces ('{' and '}').
这是个典型的收集参数式的函数,调用时如何释放呢?
"{}-{}-{}".format('2011', '01', '11')
'2011-01-11'
time_parts = ['2011', '01', '11']
"{}-{}-{}".format(time_parts[0], time_parts[1], time_parts[2])
'2011-01-11'
这样显然是可行且繁杂的,我们可以根据自己的time_parts的信息,释放参数优雅实现:
"{}/{}/{}".format(*time_parts)
'2011/01/11'
调用函数是释放参数,对应着函数定义时参数的顺序,而且这点的理解需要自己多练才会有所体会。如果您觉得我的文章能帮到您理解python基础,点赞评论🙏!