Python中经常可以见到函数声明和函数调用的时候在参数前面出现 * 或者 ** 的操作符。Python3中对其功能进行增加,下面简要总结。
Using * and ** to pass arguments to a function,即用于函数调用时的解包
When calling a function, the * operator can be used to unpack an iterable into the arguments in the function call
当调用函数时,使用*操作符可以对iterable参数进行解包
>>>fruits = ['lemon', 'pear', 'watermelon', 'tomato']
>>>print(fruits[0], fruits[1], fruits[2], fruits[3])
>lemon pear watermelon tomato
>>>print(*fruits)
lemon pear watermelon tomato
The ** operator does something similar, but with keyword arguments. The ** operator allows us to take a dictionary of key-value pairs and unpack it into keyword arguments in a function call.
简单说就是把字典进行解包
>>> date_info = {'year': "2020", 'month': "01", 'day': "01"}
>>> filename = "{year}-{month}-{day}.txt".format(**date_info)
>>> filename
'2020-01-01.txt'
这在sqlalchemy批量update的时候可以得到应用
Asterisks for packing arguments given to function
作为函数声明时的加星号的参数,可以在函数内作为iterable的变量进行解包。
from random import randint
def roll(*dice):
return sum(randint(1, die) for die in dice)
>>> roll(20)
18
>>> roll(6, 6)
9
>>> roll(6, 6, 6)
8
典型应用为python内置的print和zip函数,可以接受任意长度的参数
The ** operator also has another side to it: we can use ** when defining a function to capture any keyword arguments given to the function into a dictionary:
即将参数相应位置所有的key=value对进行接收,作为一个字典存放
def tag(tag_name, **attributes):
attribute_list = [
'{name}="{value}"'
for name, value in attributes.items()
]
return "<{tag_name} {' '.join(attribute_list)}>"
>>> tag('a', href="http://treyhunner.com")
'<a href="http://treyhunner.com">'
>>> tag('img', height=20, width=40, src="face.jpg")
'<img height="20" width="40" src="face.jpg">'
Positional arguments with keyword-only arguments
简单来说, *后面的所有参数都是关键字参数, 在调用的时候必须用关键字方式调用,不可用位置调用。
def get_multiple(*keys, dictionary, default=None):
return [
dictionary.get(key, default)
for key in keys
]
# 合法的调用
>>> fruits = {'lemon': 'yellow', 'orange': 'orange', 'tomato': 'red'}
>>> get_multiple('lemon', 'tomato', 'squash', dictionary=fruits, default='unknown')
['yellow', 'red', 'unknown']
# 非法的调用
>>> fruits = {'lemon': 'yellow', 'orange': 'orange', 'tomato': 'red'}
>>> get_multiple('lemon', 'tomato', 'squash', fruits, 'unknown')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: get_multiple() missing 1 required keyword-only argument: 'dictionary'
值得注意的是,该操作符可以单独作为一个占位符在函数的参数列表中:
def compare(a, b, *, key=None):
...