首先理解*args和**kwargs参数的用途:定义函数时作为形参,让函数可以接受任意数量的实参
用途:*args参数能让一个函数接受任意数量的位置参数,并将这些参数以元组(tuple)的形式保存args中
举个例子:
#定义求平均数的函数
def avg(first, *args):
print(first)
print(args)
return (first + sum(args))/(1 + len(args))
#测试输出
print(avg(1,2,3,4,5))
输出结果:
1
(2, 3, 4, 5)
3.0
结果解释:示例中,给函数传了5个参数。形参first接受第一个参数,而形参*args接受其余位置参数作为一个元组保存在arg变量中。
小贴士:
用途:*kwargs参数能让一个函数接受任意数量的关键字参数,并将这些参数以字典(dict)的形式保存kwargs中
举个例子:
#定义函数
def test(first, **kwargs):
print(first)
print(kwargs)
#测试调用
test('abc',a=1,b=2,c=3)
输出结果:
abc
{‘a’: 1, ‘b’: 2, ‘c’: 3}
结果解释:示例中,给函数传了4个参数。形参first接受第一个参数,而形参**kwargs接受其余关键字参数作为一个字典保存在kwarg变量中。
小贴士:
用途:同时使用*args和**kwargs参数可以让函数同时接受任意数量的位置参数和关键字参数。
注意参数的顺序:*args参数只能出现在最后一个位置参数后面,而**kwargs参数只能出现在最后一个参数。一句话概括:先常规参数,再*args参数,最后**kwargs参数。
举个例子:
#定义函数
def test(first, *args, **kwargs):
print(first)
print(args)
print(kwargs)
#测试调用
test(1,2,3,4,5,a=1,b=2,c=3)
输出结果:
1
(2, 3, 4, 5)
{‘a’: 1, ‘b’: 2, ‘c’: 3}
结果解释:示例中,给函数传了8个参数。形参first接受第一个参数,形参*args接受其余位置参数作为一个元组保存在arg变量中,形参**kwargs接受其余关键字参数作为一个字典保存在kwarg变量中。
注意:给函数传实参时需按照形参的顺序,下面这样会报错SyntaxError: positional argument follows keyword argument.
avg(1,2,3,a=1,b=2,4,5,c=3)
用途:若想将一个元组变量直接传给*args参数或者将一个字典变量直接传给**kwargs参数,需对元组和字典拆包,以简化参数的传递。
方法:在元组变量前加*(一个星号),在字典变量前加**(两个星号)
举个例子:
#定义函数
def test(*args, **kwargs):
print(args)
print(kwargs)
#定义一个元组和一个字典
tuple = (1,2,3,4,5)
dict = {'a':1,'b':2,'c':3}
#测试拆包传参
test(*tuple, **dict)
输出结果:
(1, 2, 3, 4, 5)
{‘a’: 1, ‘b’: 2, ‘c’: 3}
结果解释:拆包后实际上等效于
test(1,2,3,4,5,a=1,b=2,c=3)
但需要注意的是,如果不拆包直接传递元组和字典变量的话
test(tuple, dict)
会得到如下输出结果:
((1, 2, 3, 4, 5), {‘a’: 1, ‘b’: 2, ‘c’: 3})
{}
结果解释:tuple和dict两个参数会作为一个元组传递给*args参数,而没有实参传递给**kwargs参数。