Python的*args和**kwargs
2020-08-14 本文已影响0人
李白开水
当定义一个函数,这个函数可能会有不定长参数的时候,就会在函数的接收参数的括号的最后加上*args, **kwargs
。
- *agrs用来接收非关键字参数,以元组的形式保存,这个形参的名字叫
args
(非关键字参数就是直接传递进来的,没有名字的参数,与关键字参数相对)。 - **kwargs用来接收关键字参数,以字典的形式保存,这个形参的名字叫
kwargs
(关键字参数就是有名字的参数,比如传递进来的age=12
)。
也可以把args和kwargs起成别的名字。
当前程序:
def test(a, b, *args, **kwargs):
print(a)
print(b)
print(args)
print(kwargs)
test(11, 22)
运行一下:
D:\>python test09.py
11
22
()
{}
这时候a,b接收了11和22,而args和kwargs没有接收参数,所以为空元组和空字典。
如果再传递几个非关键字参数:
test(11, 22, 33, 44, 55, 66)
运行:
In [4]: test(11, 22, 33, 44, 55, 66)
11
22
(33, 44, 55, 66)
{}
这时候多余的非关键字参数都被传递到了args里,作为一个元组保存起来。
再传递几个关键字参数:
In [6]: test(11, 22, 33, 44, 55, 66, name="happy", age=100)
11
22
(33, 44, 55, 66)
{'name': 'happy', 'age': 100}
如果定义两个函数test01和test02,给test01传递一些参数,test01再把这些参数传递给test02:
def test01(a, b, *args, **kwargs):
print("test01")
print(a)
print(b)
print(args)
print(kwargs)
test02(a, b, args, kwargs)
def test02(a, b, *args, **kwargs):
print("test02")
print(a)
print(b)
print(args)
print(kwargs)
test01(11, 22, 33, 44, 55, 66, name="happy", age=100)
运行:
D:\>python test09.py
test01
11
22
(33, 44, 55, 66)
{'name': 'happy', 'age': 100}
test02
11
22
((33, 44, 55, 66), {'name': 'happy', 'age': 100})
{}
这时候,传给test01的除了a和b的所有参数都被test02当作一个元组存起来了。这是因为,传递给test01的是
a = 11
b = 22
args = (33, 44, 55, 66)
kwargs = {'name': 'happy', 'age': 100}
这时候再传递给test02,test02把11给了a,把22给了b,后面两个参数是一个元组一个字典,都是非关键字参数,所以就一起给了args。
所以如果想把传递给test01的参数原封不动的传给test02,就需要把元组和字典拆包,实现方法是在args前面加一个“”,在kwargs前加一个“*”。
def test01(a, b, *args, **kwargs):
print("test01")
print(a)
print(b)
print(args)
print(kwargs)
test02(a, b, *args, **kwargs)
def test02(a, b, *args, **kwargs):
print("test02")
print(a)
print(b)
print(args)
print(kwargs)
test01(11, 22, 33, 44, 55, 66, name="happy", age=100)
运行:
D:\>python test09.py
test01
11
22
(33, 44, 55, 66)
{'name': 'happy', 'age': 100}
test02
11
22
(33, 44, 55, 66)
{'name': 'happy', 'age': 100}
所以def test01(a, b, *args, **kwargs):
表示可以接收不定长的参数,以元组或字典保存。
而test02(a, b, *args, **kwargs)
表示的是拆包,把元组拆成单个元素,把字典拆成变量名=某个值
的形式。