淘先锋技术网

首页 1 2 3 4 5 6 7

一、*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字典的内容来决定是否丢弃它们。