*args 和 **kwargs 的区别

转自:

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。

扫描二维码关注公众号,回复: 4160508 查看本文章
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字典,传字典中的数据项作为键值参数。

猜你喜欢

转载自blog.csdn.net/sisqzy86/article/details/83018487
今日推荐