一、*args和**kwargs
python里的*args和**kwargs的特殊含义,他们都和函数有关,但是在函数调用和函数的声明时有着不同的意义。
一般来说,无论是函数的调用或者声明,单个星号表示有元组(或是列表)的出现,而两个星号则代表有字典出现。
二、函数的调用:
函数调用里的*和**
例如:
def check_web_server(host, port, path) :
用check_web_server('127.0.0.1', 8000, '/admin/')即可调用 这个函数。
那要是这些信息在三元组里,如:
host_info= ('www.python.org', 80, '/') #http://www.python.org/
这时候调用就会变成:
check_web_server(host_info[0], host_info[1], host_info[2])
1.单星号
这种写法不可扩展,这时候我们可以用单星号来解决这种问题。因为在调用函数时,表达式在计算一个带星号前缀的元组或列表时,会将其打开。
所以上面的元组函数调用,我们可以写成他的等价形式:
check_web_server(*host_info)
2.双星号
双星号对应的字典的用法也是类似的。现在我们创建一个和('www.python.org', 80, '/')相似内容的字典。
host_info= {'host': 'www.python.org', 'port': 80, 'path': '/'}
于是函数的调用就变成了:
check_web_server(**host_info)
它告诉函数在打开字典时,每个键是参数的名字,同时对应的值是函数调用的参数。它就等于:
check_web_server(host='www.python.org', port=80, path='/')
三、函数的声明
函数声明里的*和**
函数声明里的*和**虽然相似但作用不同:它们让Python得以支持变长参数(varargs),即函数可以接受任何数量的参数。
当定义一个有三个参数的函数时(没有默认值的参数),调用的时候必须传入正好三个参数。默认参数虽然引入了一些灵活性,但函数依然受制于所定义参数的最大数目。
如果需要更大的灵活性,我们可以用单星号表示的元组来定义一个变长参数,这个元组包含了所有的元素。现在我们来创建一个这样的“daily sales total”函数:
def daily_sales_total(*all_sales) :
total = 0.0
for each_sale in all_sales :
total += float(each_sale)
return total
相应的合法的函数调用有:
daily_sales_total()
daily_sales_total(10.00)
daily_sales_total(5.00, 1.50, '128.75') #Any type is allowed,not just flosts
不管你向这个函数传递多少参数,他都能够处理。all_sales就是一个包含了所有参数的元组(这就是我们要在函数定义里迭代all_sales的原因)。
你还可以把普通参数和和变长参数混在一起使用,这时候vararg就会捕捉所有剩下的参数,例如现在这个假设的check_web_server函数定义就能接受额外的参数了。
def check_web_server(host, port, path, *args):
注意:在函数定义里要使用变长参数 时,所有必须出现的参数一定先出现,然后是有默认值的参数,最后才是变长参数。
类似的,你也可以在函数声明里用双星号来接受任意数目的关键字参数,它们会在函数被调用时导入到另一个字典中。
def check_web_server(host, port, path, *args, **kwargs):
这个函数必须接受初始的三个参数,但是也能接受随后任何数目的参数或是关键字参数:在函数内部,我们可以分别检查args元组和kwargs字典的内容来决定是否丢弃它们。