*args和**kwargs是什么意思?

def foo(x, y, *args):
def bar(x, y, **kwargs):

当前回答

对于那些通过实例学习的人!

*的目的是让您能够定义一个函数,该函数可以接受作为列表提供的任意数量的参数(例如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   = {}
# ----------------------------------------------------------------------

注意事项

**专为词典保留。非可选参数赋值首先发生。不能两次使用非可选参数。如果适用,**必须始终在*之后。

其他回答

在函数中同时使用两者的一个好例子是:

>>> 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')
{}

*args(或*any)表示每个参数

def any_param(*param):
    pass

any_param(1)
any_param(1,1)
any_param(1,1,1)
any_param(1,...)

注意:不能将参数传递给*args

def any_param(*param):
    pass

any_param() # will work correct

*参数的类型为元组

def any_param(*param):
    return type(param)

any_param(1) #tuple
any_param() # tuple

用于访问不使用的元素*

def any(*param):
    param[0] # correct

def any(*param):
    *param[0] # incorrect

**千瓦时

**kwd或**任何这是字典类型

def func(**any):
    return type(any) # dict

def func(**any):
    return any

func(width="10",height="20") # {width="10",height="20")


*args和**kwargs:允许您向函数传递可变数量的参数。

*args:用于向函数发送非关键字可变长度参数列表:

def args(normal_arg, *argv):
    print("normal argument:", normal_arg)

    for arg in argv:
        print("Argument in list of arguments from *argv:", arg)

args('animals', 'fish', 'duck', 'bird')

将产生:

normal argument: animals
Argument in list of arguments from *argv: fish
Argument in list of arguments from *argv: duck
Argument in list of arguments from *argv: bird

**夸尔斯*

**kwargs允许您向函数传递关键字可变长度的参数。如果要处理函数中的命名参数,应使用**kwargs。

def who(**kwargs):
    if kwargs is not None:
        for key, value in kwargs.items():
            print("Your %s is %s." % (key, value))

who(name="Nikola", last_name="Tesla", birthday="7.10.1856", birthplace="Croatia")  

将产生:

Your name is Nikola.
Your last_name is Tesla.
Your birthday is 7.10.1856.
Your birthplace is Croatia.

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循环等方面的含义。

单*表示可以有任意数量的额外位置参数。foo()可以像foo(1,2,3,4,5)一样调用。在foo()的主体中,param2是一个包含2-5的序列。

双**表示可以有任意数量的额外命名参数。bar()可以像bar(1,a=2,b=3)一样调用。在bar()的主体中,param2是一个字典,其中包含{‘a‘:2,‘b‘:3}

使用以下代码:

def foo(param1, *param2):
    print(param1)
    print(param2)

def bar(param1, **param2):
    print(param1)
    print(param2)

foo(1,2,3,4,5)
bar(1,a=2,b=3)

输出为

1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}