在看Django源码时常常会看到*args和**kwargs的运用,这里做个总结。*与**的运用分两种情况。
这种情况与C语言中的可变长参数列表情形很相似。
def check_web_server(host,port,path,*args,**kwargs):
... ...
函数这样定义表示,它至少需要三个参数,所以你可以这样调用
check_web_server('localhost',80,'/index')
此时函数的参数args就为一个空tuple,即(),而kwargs就是一个空字典,即{}。你也可以传递更多的信息,比如
check_web_server('localhost',80,'/index','nothing',50,method='get')
这样结果是,args=('nothing',50),kwargs={'method':'get'}
,所以,函数定义里的*args用于接受任意个数的单值参数,而kwargs接受任意个数的键值对。
当然你没有必要同时使用*args和**kwargs,这里只是举个例子罢了。你也完全不必使用args和kwargs这两个名字,不过,大家似乎都喜欢使用这两个名字。
所以如果你定义def f(*args,**kwargs)
那么表示该函数可以接受任何形式,任意多的参数。
如果定义了一个函数def check_web_server(host,port,path)
,你可以使用
check_web_server('localhost',80,'index')
进行调用,然而,有时你不记得参数顺序,为了方便你可以这样调用,
check_web_server(path='/index',port='80',host='localhost')
*和**提供了更方便的调用方法,以解决参数过多的问题。你可以这样调用:
request=('localhost','80','/index')
check_web_server(*request)
进行调用也可以这样进行调用:
request={'port':80,'path':'/index','host':'localhost'}
check_web_server(**request)
进行调用。其实还是很容易理解的,*request就相当于把一个tuple进行分解,结果就是直接传参。而**request就相当于对一个dict进行分解,结果就是键值对传参。