Python中的*args和**kwargs
一、*args
*args由 * 和args两部分组成。其中,*的作用有有两个,分别是打包参数(pack)和拆分参数(unpack)。
- 打包参数(pack):* 作为打包参数,函数接收实参时,按顺序分给函数形参。如果遇到 * 的形参,那么就把还未分配出去的实参以元组形式打包(pack),分配给那个带 * 的形参。
- 拆分参数(unpack):把打包了的实参(元组或列表),拆分(unpack)成单个的,依次赋值给函数的形参。
例1:* 打包参数
def foo(*number):
print(number)
foo(1,2,3,4,5)
(1, 2, 3, 4, 5)
[Finished in 0.2s]
分析:若number前不加 * 号,那么foo()只能接收一个参数,参数给多给少都会报错。而加上 * ,就能成功运行。这是因为 * 把函数foo接收到的多个参数1,2,3,4,5,打包成了元组(1,2,3,4,5),赋值给了形参number。
例2:* 打包参数
def foo(a,*number):
print('a:',a)
print('number:',number)
for i in number:
print(i)
print(type(number))
foo(1,2,3,4,5)
a: 1
number: (2, 3, 4, 5)
2
3
4
5
<class 'tuple'>
[Finished in 0.2s]
分析:第一个参数1被形参a接收,形参number接收的实参为(2,3,4,5)。
例3:* 打包参数
def foo(a,b,*number,c):
print('a:',a)
print('b' ,b)
print('number:',number)
print('c', c)
foo(1,2,3,4,5)
Traceback (most recent call last):
File "D:\软件\Sublime Text 3\ydd_python_code\chazhi.py", line 40, in <module>
foo(1,2,3,4,5)
TypeError: foo() missing 1 required keyword-only argument: 'c'
[Finished in 0.2s with exit code 1]
分析:* 作为打包参数,函数接收实参时,按顺序分给函数形参。如果遇到 * 的形参,那么就把还未分配出去的实参以元组形式打包(pack),分配给那个带 * 的形参。首先把第一个参数1传给a,然后把第二个参数传给b,接着剩下的参数全被number接收了,因此没有实参传入c,会报错。
例4:* 打包参数
def foo(a,b,*number,c):
print('a:',a)
print('b' ,b)
print('number:',number)
print('c', c)
print('-------------------')
foo(a=1,b=2,c=3)
foo(c=3,a=1,b=2)
foo(1,2,c=3)
foo(1,2,3,4,(5,6),[7,8],c=9)
a: 1
b 2
number: ()
c 3
-------------------
a: 1
b 2
number: ()
c 3
-------------------
a: 1
b 2
number: ()
c 3
-------------------
a: 1
b 2
number: (3, 4, (5, 6), [7, 8])
c 9
-------------------
[Finished in 0.2s]
分析:从本例可以看出 * 作为打包参数,函数接收实参时,是按顺序分给函数形参。对于foo(1,2,3,4,(5,6),[7,8],c=9)这样的带 * number的形式,先把1传给a,再把2传给b,再向后将c=9之前的所有还未分配出去的实参以元组形式打包分配给number,最后将9传给c。【注:args只是一个约定俗成的形参写法,写为其他的也可以,比如本例中的number,只是不利于统一形式。】
例5:* 拆分参数(unpack)
def bar (m,a,b,c,n):
print(a,b,c)
bar(0,*[1,2,3],2)
1 2 3
[Finished in 0.2s]
分析:将打包了的实参[1,2,3]拆分为1,2,3,传给a,b,c。
二、**kwargs
**kwargs由 ** 和kwargs两部分组成。其中,**的作用有有两个,分别是打包参数(pack)和拆分参数(unpack)。
- 打包参数(pack):** kwargs把多个关键字参数打包成字典。
- 拆分参数(unpack):** kwargs把字典的键值拆成单个的,依次赋值给函数的形参。
例1:** 打包参数
def bar(m,**number):
print('m:', m)
print('number:', number)
bar(0.01,a=1,b=2,c=3)
m: 0.01
number: {'a': 1, 'b': 2, 'c': 3}
[Finished in 0.2s]
例2:** 拆分参数
def bar(m,a,b,c):
print('m:',m)
print('a,b,c:', a,b,c)
bar(0.01,**{'a':1,'b':2,'c':3})
m: 0.01
a,b,c: 1 2 3
[Finished in 0.2s]
分析:【注意】用 ** 方式拆解字典给形参赋值时,需要字典的键名和函数形参一致,否则会报错。
例:*args 和 **kwargs混用
def bar(a,*args,b,**kwargs):
print('a:', a)
print('args:', args)
print('b:', b)
print('kwargs:', kwargs)
bar(1,2,3,4,b=6,mm=0,nn=1,pp=2)
a: 1
args: (2, 3, 4)
b: 6
kwargs: {'mm': 0, 'nn': 1, 'pp': 2}
[Finished in 0.2s]
参考博客:https://blog.csdn.net/lllxxq141592654/article/details/81288741?utm_source=app
每日金句:考虑一千次,不如做一次;犹豫一万次,不如实践一次。华丽地跌倒,胜过无畏的彷徨。Fight!