*args和**kwargs是什么意思?
def foo(x, y, *args):
def bar(x, y, **kwargs):
*args和**kwargs是什么意思?
def foo(x, y, *args):
def bar(x, y, **kwargs):
当前回答
在函数中同时使用两者的一个好例子是:
>>> def foo(*arg,**kwargs):
... print arg
... print kwargs
>>>
>>> a = (1, 2, 3)
>>> b = {'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(*a,**b)
(1, 2, 3)
{'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(a,**b)
((1, 2, 3),)
{'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(a,b)
((1, 2, 3), {'aa': 11, 'bb': 22})
{}
>>>
>>>
>>> foo(a,*b)
((1, 2, 3), 'aa', 'bb')
{}
其他回答
对于那些通过实例学习的人!
*的目的是让您能够定义一个函数,该函数可以接受作为列表提供的任意数量的参数(例如f(*myList))。**的目的是通过提供字典(例如f(**{'x':1,'y':2}))来提供函数的参数。
让我们通过定义一个函数来展示这一点,该函数接受两个正常变量x,y,并且可以接受更多的参数作为myArgs,并且可以接收更多的参数为myKW。稍后,我们将展示如何使用myArgDict喂养y。
def f(x, y, *myArgs, **myKW):
print("# x = {}".format(x))
print("# y = {}".format(y))
print("# myArgs = {}".format(myArgs))
print("# myKW = {}".format(myKW))
print("# ----------------------------------------------------------------------")
# Define a list for demonstration purposes
myList = ["Left", "Right", "Up", "Down"]
# Define a dictionary for demonstration purposes
myDict = {"Wubba": "lubba", "Dub": "dub"}
# Define a dictionary to feed y
myArgDict = {'y': "Why?", 'y0': "Why not?", "q": "Here is a cue!"}
# The 1st elem of myList feeds y
f("myEx", *myList, **myDict)
# x = myEx
# y = Left
# myArgs = ('Right', 'Up', 'Down')
# myKW = {'Wubba': 'lubba', 'Dub': 'dub'}
# ----------------------------------------------------------------------
# y is matched and fed first
# The rest of myArgDict becomes additional arguments feeding myKW
f("myEx", **myArgDict)
# x = myEx
# y = Why?
# myArgs = ()
# myKW = {'y0': 'Why not?', 'q': 'Here is a cue!'}
# ----------------------------------------------------------------------
# The rest of myArgDict becomes additional arguments feeding myArgs
f("myEx", *myArgDict)
# x = myEx
# y = y
# myArgs = ('y0', 'q')
# myKW = {}
# ----------------------------------------------------------------------
# Feed extra arguments manually and append even more from my list
f("myEx", 4, 42, 420, *myList, *myDict, **myDict)
# x = myEx
# y = 4
# myArgs = (42, 420, 'Left', 'Right', 'Up', 'Down', 'Wubba', 'Dub')
# myKW = {'Wubba': 'lubba', 'Dub': 'dub'}
# ----------------------------------------------------------------------
# Without the stars, the entire provided list and dict become x, and y:
f(myList, myDict)
# x = ['Left', 'Right', 'Up', 'Down']
# y = {'Wubba': 'lubba', 'Dub': 'dub'}
# myArgs = ()
# myKW = {}
# ----------------------------------------------------------------------
注意事项
**专为词典保留。非可选参数赋值首先发生。不能两次使用非可选参数。如果适用,**必须始终在*之后。
带*Args和**kwargs的“无限”Args
*args和**kwargs只是向函数输入无限字符的一种方式,例如:
def print_all(*args, **kwargs):
print(args) # print any number of arguments like: "print_all("foo", "bar")"
print(kwargs.get("to_print")) # print the value of the keyworded argument "to_print"
# example:
print_all("Hello", "World", to_print="!")
# will print:
"""
('Hello', 'World')
!
"""
根据尼克的回答。。。
def foo(param1, *param2):
print(param1)
print(param2)
def bar(param1, **param2):
print(param1)
print(param2)
def three_params(param1, *param2, **param3):
print(param1)
print(param2)
print(param3)
foo(1, 2, 3, 4, 5)
print("\n")
bar(1, a=2, b=3)
print("\n")
three_params(1, 2, 3, 4, s=5)
输出:
1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}
1
(2, 3, 4)
{'s': 5}
基本上,任何数量的位置参数都可以使用*args,任何命名参数(或kwargs又名关键字参数)都可以使用**kwargs。
上下文
python 3.x使用打开包装**与字符串格式一起使用
与字符串格式一起使用
除了本主题中的答案之外,还有一个其他地方没有提到的细节。这扩展了Brad Solomon的答案
使用python str.format时,使用**解包也很有用。
这有点类似于使用python f-string f-string所做的操作,但增加了声明dict以保存变量的开销(f-string不需要dict)。
快速示例
## init vars
ddvars = dict()
ddcalc = dict()
pass
ddvars['fname'] = 'Huomer'
ddvars['lname'] = 'Huimpson'
ddvars['motto'] = 'I love donuts!'
ddvars['age'] = 33
pass
ddcalc['ydiff'] = 5
ddcalc['ycalc'] = ddvars['age'] + ddcalc['ydiff']
pass
vdemo = []
## ********************
## single unpack supported in py 2.7
vdemo.append('''
Hello {fname} {lname}!
Today you are {age} years old!
We love your motto "{motto}" and we agree with you!
'''.format(**ddvars))
pass
## ********************
## multiple unpack supported in py 3.x
vdemo.append('''
Hello {fname} {lname}!
In {ydiff} years you will be {ycalc} years old!
'''.format(**ddvars,**ddcalc))
pass
## ********************
print(vdemo[-1])
TL;博士
以下是python编程中*和**的6种不同用例:
要使用*args:def foo(*args):pass接受任意数量的位置参数,这里foo接受任意数目的位置参数,即,以下调用是有效的foo(1)、foo(2,'bar')若要使用**kwargs:def foo(**kwargs):pass接受任意数量的关键字参数,此处“foo”接受任意数量关键字参数,即,以下调用是有效的foo(name='Tom')、foo(name='Tom',age=33)要使用*args,**kwargs:def foo(*args、**kwargs):pass接受任意数量的位置和关键字参数,这里foo接受任意数目的位置和关键词参数,即,以下调用是有效的foo(1,name='Tom')、foo(2,'bar',name='Tom',age=33)要使用*:def foo(pos1,pos2,*,kwarg1):pass强制只接受关键字参数,这里*表示foo只接受pos2之后的关键字参数,因此foo(1,2,3)引发TypeError,但foo(1,2,kwarg1=3)正常。为了表示对更多位置参数不再感兴趣,请使用*_(注意:这只是一个约定):def foo(bar,baz,*_):pass表示(按照约定)foo在工作中只使用bar和baz参数,而忽略其他参数。为了表示对更多关键字参数不再感兴趣,请使用**_(注意:这只是一个约定):def foo(bar,baz,**_):pass意味着(按照约定)foo在工作中只使用bar和baz参数,而忽略其他参数。
好处:从python 3.8开始,可以在函数定义中使用/来强制执行仅限位置的参数。在以下示例中,参数a和b仅是位置性的,而c或d可以是位置性或关键字,e或f必须是关键字:
def f(a, b, /, c, d, *, e, f):
pass
好处2:对同一个问题的回答也带来了一个新的视角,它分享了*和**在函数调用、函数签名、for循环等方面的含义。