说明
在再谈二者区别前,先要说明的是,语法的区别是* 和** 这两个符号影响,而*args和**kwargs只是约定的非强制性的。就使用场景而言,可以分为在function definition和function call来讨论
function definition
出现在函数定义时,当我们不确定函数的参数个数时,*args允许你传入任意数量的参数,**kwargs可以传入任意数量的关键字参数,具体如何使用,又如何表现? 我们先分析代码:
def foo1(*args):
print args
foo1('a', 'b', [1, 2, 'c'])
# output: ('a', 'b', [1, 2, 'c'])
def foo2(**kwargs):
print kwargs
foo2(name='zz', address='yy', id=[1,2])
# output: {'id': [1, 2], 'name': 'zz', 'address': 'yy'}
def foo3(i, *args, **kwargs):
print i, args, kwargs
foo3(1)
# output: 1 () {}
foo3(1, 2, 3)
# output: 1 (2, 3) {}
foo3(1, name='zz', address='yy')
# output: 1 () {'name': 'zz', 'address': 'yy'}
foo3(1, 2, 3, name='zz', address='yy')
# output: 1 (2, 3) {'name': 'zz', 'address': 'yy'}
从上面的例子,我们总结如下几点:
*args 和**kwargs可以单独使用
*args和**kwargs可以一起使用
一起使用时,*args必须在**kwargs前面
function call
出现在函数调用时,*会把list或者tuple的元素unpack,作为一个个参数传递,而**会把dict作为关键字参数传递,需要注意的是,unpack后的参数数目要和函数定义保持一致,看如下几个例子:
def foo1(a, b, c):
print a, b, c
i = [1, 2, 3]
foo1(*i)
# output: 1 2 3
def foo2(a, b, c=9):
print a, b, c
d = {'b': 2, 'a': 3}
foo2(**d)
# output: 3 2 9
def foo3(a, b, *args, **kwargs):
print a, b, args, kwargs
a = [1, 2, 3, 4, 5, 6]
b = {'name': 'xx', 'address': 'yy'}
foo3(*a, **b)
# output: 1 2 (3, 4, 5, 6) {'name': 'xx', 'address': 'yy'}
从上面的例子,我们总结如下几点:
*会把list或者tuple分解为一个个参数传递给函数
**会把dict转成关键字参数
函数定义和函数调用,可以同时出现*或者**,如foo3
出现在函数调用时,一定要注意参数匹配问题