2019年9月13日 / 742次阅读 / Last Modified 2019年10月11日
函数
Python的各种学习资料中,常常见到函数有一个**kw这样的参数,有的时候出现在函数定义时,有的时候出现在函数调用时,有的时候还与其它参数一并存在。本文尝试彻底将这样的参数用法搞清楚。
有**kw参数的函数,会将调用时的key=value参数全部打包到kw这个dict对象内,请看下面示例:
>>> def kwt1(**kw):
... print(locals())
...
>>> kwt1(a=1,b=2,c=3)
{'kw': {'a': 1, 'b': 2, 'c': 3}}
在函数内部,只有一个dict类型的kw参数,调用时传入的abc三个参数,都已经打包进kw内。因此,这种定义函数的方式,实现了函数不限参数个数的效果。
>>> def kwt2(a,b=5,**kw):
... print(locals())
...
>>> kwt2(1,b=9,c=1,d=2,e=3)
{'a': 1, 'b': 9, 'kw': {'c': 1, 'd': 2, 'e': 3}}
>>> kwt2(1,9,c=1,d=2,e=3)
{'a': 1, 'b': 9, 'kw': {'c': 1, 'd': 2, 'e': 3}}
>>> kwt2(1,c=1,d=2,e=3)
{'a': 1, 'b': 5, 'kw': {'c': 1, 'd': 2, 'e': 3}}
这段示例代码,在**kw之前,还有两个参数,一个位置参数,一个key=value参数,有默认值。此函数在调用时,始终会将前面两个参数排除在kw这个dict之外。
**kw对于函数内部而言,是一个dict类型的参数,而不是多个。多个参数的实现,全部都在kw这个dict内部。而且,kw这个参数,与其他参数并列。
当**kw出现在函数调用时,就是将kw这个dict展开,将所有的key=value传入函数。我们继续使用上文的 kwt1和kwt2这两个函数举例:
>>> d1 = {'a':1,'b':2,'c':3}
>>> kwt1(**d1)
{'kw': {'a': 1, 'b': 2, 'c': 3}}
>>> kwt2(1,2,**d1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: kwt2() got multiple values for argument 'a'
>>> kwt2(**d1)
{'a': 1, 'b': 2, 'kw': {'c': 3}}
在调用kwt1函数时,有两个步骤,首先将d1这个dict展开成a=1,b=2,c=3,传给kwt1函数(这个特性叫unpacking参数),然后kwt1函数再将abc三个参数,打包进函数内部的kw参数。调用时是展开,定义时是打包。
在调用kwt2函数时,第1次调用时出错,是因为第1个位置参数就是a,而d1展开后,里面还有一个a。第2次调用正确,而且,kwt2函数内部的kw参数,只包含c这个选项。这部分的精妙,要好好体会一下!!先将dict变量展开,然后调用函数,调用时,再打包。
>>> kwt1(**d1,d=5,e=6)
{'kw': {'a': 1, 'b': 2, 'c': 3, 'd': 5, 'e': 6}}
再来调用一次kwt1函数,这一次除了展开d1之外,在调用处,还增加了d和e两个参数。函数展开d1,然后把d和e一起,打包进函数内部的kw变量。
总结一下:函数定义时的**kw,会将调用时的参数打包进kw;函数调用时的**kw,会将kw展开后再调用函数。这个过程,注意其它参数,注意参数的key不要重复。
-- EOF --
本文链接:https://www.pynote.net/archives/1128
《Python函数有一个**kw这样的参数?》有2条留言
前一篇:Python带条件判断的赋值语句
后一篇:让Label像Button一样可以点击
©Copyright 麦新杰 Since 2019 Python笔记
两个星号就代表的是dict对象的packing或unpacking! [ ]
定义中的**kw,packing arguments;调用时的**kw,unpacking kw。 [ ]