我在学习OpenStack的过程中遇到了大量的如下形式的代码段:
args['body'] = json.loads(request.body)
result = method(request=request, **args)
在这里,**args是作为函数的实参,经过写代码测试,发现要分两种情况讨论:
1.**args作为函数的形参:
def test(**args):
print args
test(a='1', b=2)
运行结果:
root@ubuntu:/home/codes/kwargs# python 2.py
{'a': '1', 'b': 2}
结论:**args作为函数形参时,表示需要接收默认类型的参数。否则会报以下的错误
a = 1
def test(**args):
print args
test(a)
Traceback (most recent call last):
File "2.py", line 8, in <module>
test(a)
TypeError: test() takes exactly 0 arguments (1 given)
2.**args作为函数的实参
args = {}
args['name'] = 'jack'
def test(name):
print name
test(**args)
运行结果:
root@ubuntu:/home/codes/kwargs# python 2.py
jack
但是,如果我们把传入参数改变一下
args = {}
args['name'] = 'jack'
args['id'] = 12345
def test(name):
print name
test(**args)
结果为:
root@ubuntu:/home/codes/kwargs# python 2.py
Traceback (most recent call last):
File "2.py", line 7, in <module>
test(**args)
TypeError: test() got an unexpected keyword argument 'id'
这是由于**args被翻译为了name = 'jack', 'id' = 12345的缘故。我们只需给test函数增加一个参数即可:
args = {}
args['name'] = 'jack'
args['id'] = 12345
def test(name, id):
print name
print id
test(**args)
结果:
root@ubuntu:/home/codes/kwargs# python 2.py
jack
12345
结论:**args作为形参时,表示将字典类型的数据转化为默认默认参数,否则会出现如下的报错
a = 1
def test(name, id):
print name
print id
test(**a)
报错:
Traceback (most recent call last):
File "2.py", line 8, in <module>
test(**a)
TypeError: test() argument after ** must be a mapping, not int
总结: 当**args作为函数形参时,表示接收0个或任意个默认参数;当**args作为实参时,表示将字典转换为默认参数。对于加一个星的*args也有类似的用法