主要介绍一下*args和**kwargs的区别,其实更准确的说是,*和**。实际上真正的Python参数传递语法是*和**。*args和**kwargs只是一种约定俗成的编程实践。我们也可以写成*vars和**kvars。

*args和**kwargs一般是用在函数定义的时候。作用是允许定义的函数接受任意数目的参数。下面来分别介绍一下:

*args

*args用来表示函数接收可变长度的非关键字参数列表作为函数的输入。
看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
def hello(name, age, *args):
print "do something..."
print name, age
print args

>>> hello("Tom", "12")
do something...
Tom 12
()
>>> hello("Tom", "12", "Black")
do something...
Tom 12
('Black',)

备注:arg的输出是一个元组,如果只输入两个参数,那么可变参数args就是一个空元组。只要超过2个参数,多余的就会存储在args元组中。

**kwargs

**kwargs表示函数接收可变长度的关键字参数字典作为函数的输入。当我们需要函数接收带关键字的参数作为输入的时候,应当使用**kwargs。
看下面的例子:

1
2
3
4
5
6
7
def hello(**kwargs):
print kwargs

>>>hello(name="Black")
{'name': 'black'}
>>> hello(name="Tom", age="22")
{'age': '22', 'name': 'Tom'}

备注:kwargs输出为字典,关键词作为字典的key,参数作为值保存在kwargs中。

当输入为字典时:

1
2
3
4
5
6
def hello(**kwargs):
print kwargs

>>> d = dict(name="Tom", age=22)
>>>hello(**d)
{'age': '22', 'name': 'Tom'}

输入完全一样,相当于直接输出字典d,由此对于数据库连接,日志配置一种简单的情况就是配置成字典,然后直接传入字典,代码变得更加简洁。

混合参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def hello(name, age, *args, **kwargs):
print name, age
print args
print kwargs

>>>hello("Black", "22", "177", hobby="math")
Black 22
('177',)
{'hobby': 'math'}
>>>hello("Black", "22", length="177", hobby="math")
Black 22
()
{'hobby': 'math', 'length': '177'}
>>>hello(name="Black", age="22", length="177", hobby="math")
Black 22
()
{'hobby': 'math', 'length': '177'}

注意:标准参数与*args、**kwargs在使用时的顺序:

1
some_func(fargs, *args, **kwargs)

使用*args和**kwargs 来调用函数

假设,你有这样一个小函数:

1
2
3
4
def test_args_kwargs(arg1, arg2, arg3):
print("arg1:", arg1)
print("arg2:", arg2)
print("arg3:", arg3)

你可以使用args或*kwargs来给这个小函数传递参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 首先使用 *args
>>> args = ("two", 3, 5)
>>> test_args_kwargs(*args)
arg1: two
arg2: 3
arg3: 5

# 现在使用 \*\*kwargs:
>>> kwargs = {"arg3": 3, "arg2": "two", "arg1": 5}
>>> test_args_kwargs(**kwargs)
arg1: 5
arg2: two
arg3: 3

参考资料