转自:
https://www.cnblogs.com/lidaxian/p/7767364.html
写得非常清楚,可以理解透彻.
1. 通过一个函数调用来理解’*’的作用
它拆开数列’l’的数值作为位置参数,并吧这些位置参数传给函数’fun’来调用。
因此拆数列、传位置参数意味着fun(*l)与fun(1,2,3)是等效的,因为l = [1,2,3]。
2. 通过一个函数的定义来理解’*args’的含义
它接收元组作为位置参数,而非是常见的参数列表。在这里,”args”是个元组。在我们解释中不要担心”常见的参数”这部分的理解,这个会在接下来的例子中逐渐明了。在上个例子中,调用函数打印”args”时,他会打印元组中包含的所有数值。
我们重新定义函数,”*args”与”常规参数列表”混合使用
def fun(a, *args): print("a is ", a) print("args is ", args)
fun(11,12,34,43)
很容易看到,’a’打印出为11,即第一个位置参数。’a’之后只一个参数’*args’.因此,’args’接收除常规参数之外的位置参数作为元组。因此元组args作为元组接收12,34和43。
fun(91)
在这里,我们传的唯一一个参数分配给了常规参数’a’.因此,’args’接收到一个空元组。
‘args’既然是元组,我们就可以遍历它。
现在我们考虑使用所有能得到的参数的场景。我们需要使用两个函数,第一个函数带有任意个参数,并通过另外一个函数计算除第一参数的其他参数之和。奇怪的用例,但我们只需回顾我们目前所做的。我们的目的就是在一个函数中获取可变参数,并把这些参数餐给另一个函数。
def calculate_sum(*args): return sum(args) def ignore_first_calculate_sum(a,*iargs): required_sum = calculate_sum(*iargs) print("sum is ", required_sum)
我们可以传任意个参数给这个函数。第一个参数被常规参数’a’接收,其他参数被’iargs’作为元组接收。正如我们考虑的案例,计算除第一个参数之外的其他参数的和。因此,我们用’a’接收第一个参数,’iargs’是包含其他参数的元组。我们用到函数’calculate_sum’,但’calculate_sum’需要多个位置参数作为元组传给’args’。所以在函数’ignore_first_calculate_sum’需要拆元组’iargs’,然后将元素作为位置参数传给’calculate_sum’.注意,用’*’拆元组。
3. 通过一个函数的调用来理解’**’的作用
使用”**”调用函数,这种方式我们需要一个字典.注意:在函数调用中使用”*”,我们需要元组;在函数调用中使用”**”,我们需要一个字典
def fun(a, b, c): return a, b, c d={'b':5, 'c':7} fun(1, **d)
它unpack字典,并将字典中的数据项作为键值参数传给函数。因此,”fun(1, **d)”的写法与”fun(1, b=5, c=7)”等效.
4. 通过一个函数的定义来解’**kwargs’的含义
def fun(a, **kwargs): print(a, kwargs)
此函数只用一个位置参数,因为常规参数列表中只有一个变量’a’.但是通过”**kwargs”,可以传多个键值参数。
fun(1, b=4, c=5)
用”**kwargs”定义函数,kwargs接收除常规参数列表职位的键值参数字典。在这里’kwargs’是个字典。
def fun(a, **kwargs): print("a is ", a) print("We expect kwargs 'b' and 'c' in this function") print("b is ", kwargs['b']) print("c is ", kwargs['c']) fun(1, b=3, c=5) fun(1, b=3, d=5)
上面的调用,位置参数’a’和键值参数’b’都打印出来了。传入的其他键值参数是’d’,函数需要键值参数’c’,并从字典’kwargs’获取。但没有传入键值’c’,引发KeyError.如果传入了键值’c’就不会引发这个错误
fun(1, b=3, d=5, c=9)
由于’**kwargs’在函数参数列表中,我们可以传任意个键值参数。上面的调用传入了”d”,但函数并没用到。
fun(1, {'b':2, 'c':34}) fun(1, **{'b':2, 'c':34})
尽管’kwargs’接收键值参数作为一个字典,但你不能传一个字典作为位置参数给’kwargs’.你可以像上面那样调用:
在一个字典前使用”**”可以unpack字典,传字典中的数据项作为键值参数。