一般来说,无论是函数调用还是声明,单个星号表示元组(或是列表)“出现”,而两个星号则代表附近有字典“出没”。
函数调用里的*和**
check_web_server(host, port, path):
用check_web_server('127.0.0.1', 80, '/admin/')即可调用和这个函数。
那要是这些信息在一个三元组里的话,例如host_info=('www.python.org', 80, '/'),这时调用就会变成check_web_server(host_info[0], host_info[1], host_info[2])。
这时单星号就可以解决,用下面的例子和上面的代码是等价的:check_web_server(*host_info)。
而双星号对字典的用法也类似,host_info={'host': 'www.python.org', 'port': 80, 'path': '/'},
于是函数的调用就变成了:check_web_server(**host),这就告诉函数在打开字典时,每个键时参数的名字,同时对应的值是函数调用的参数。
即它就等于check_web_server('host': 'www.python.org', 'port': 80, 'path': '/')
函数声明里的*和**
它们让python得以支持变长参数,函数可接受任何数量的参数。
当定义一个三个参数的函数时(没有默认值的参数),调用者必须传入正好三个参数。
如果需要更大的灵活性,则可以用单星号表示的元组来定义一个变长参数,创建一个daily_sales_total函数:
def daily_sales_total(*all_sales):
total=0.0
for each_sale in all_sales:
total+=float(each_sale)
return total
相应地合法函数调用有:
def daily_sales_total()
def daily_sales_total(10.00)
def daily_sales_total(5.00, 1.50, '128.75')
还可以把普通参数和变长参数混在一起使用,如def check_web_server(host, port, path, *args):
注意:在函数定义里使用变长参数时,所有必须出现的参数一定先出现,然后是有默认值的参数,最后才是变长参数。
类似的,也可以在函数声明里用双星号来接受任意数目的关键字参数,它们会在函数被调用的时候导入到一个字典里去
def check_web_server(host, port, path, *args, **kwargs):
实际上,还有一种全部由变长参数组成的所谓通用python方法:def f(*args, **kwargs):
这样的函数可以按照f(), f(a, b, c), f(a, b, foo=c, bar=d)等任何方式调用,它可以接受任意形式的输入了。
动态创建字典:
>>> bobagrs=dict((f+ '_contains', 'bob') for f in ('title', 'subtitle', 'text', 'byline'))
>>> bobagrs
{'title_contains': 'bob', 'byline_contains': 'bob', 'subtitle_contains': 'bob', 'text_contains': 'bob'}
>>> bo=((f+ '_contains', 'bob') for f in ('title', 'subtitle', 'text', 'byline'))
>>> bo
<generator object <genexpr> at 0x1067705a0>
dict(bo)就可以把一个迭代器转换成字典类型。
>>> list(bo)
[('title_contains', 'bob'), ('subtitle_contains', 'bob'), ('text_contains', 'bob'), ('byline_contains', 'bob')]
>>> a={'a':1, 'b':2}
>>> a.items()
[('a', 1), ('b', 2)]
>>> dict(a)
{'a': 1, 'b': 2}