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

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

当前回答

TL;博士

它将传递给函数的参数分别打包到函数体中的list和dict中。当您这样定义函数签名时:

def func(*args, **kwds):
    # do stuff

它可以用任意数量的参数和关键字参数调用。非关键字参数被打包到函数体内名为args的列表中,关键字参数被包装到函数体内称为kwds的dict中。

func("this", "is a list of", "non-keyowrd", "arguments", keyword="ligma", options=[1,2,3])

现在在函数体内部,当调用函数时,有两个局部变量,args是一个值为[“this”,“is a list of”,“non-keyword”,“arguments”]的列表,kwds是一个具有值为{“keyword”:“ligma”,“options”:[1,2]}的dict


这也反过来起作用,即从呼叫者一侧起。例如,如果函数定义为:

def f(a, b, c, d=1, e=10):
    # do stuff

您可以通过打开调用范围中的可迭代项或映射来调用它:

iterable = [1, 20, 500]
mapping = {"d" : 100, "e": 3}
f(*iterable, **mapping)
# That call is equivalent to
f(1, 20, 500, d=100, e=3)

其他回答

*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.

给定一个有3项作为参数的函数

sum = lambda x, y, z: x + y + z
sum(1,2,3) # sum 3 items

sum([1,2,3]) # error, needs 3 items, not 1 list

x = [1,2,3][0]
y = [1,2,3][1]
z = [1,2,3][2]
sum(x,y,z) # ok

sum(*[1,2,3]) # ok, 1 list becomes 3 items

想象一下这个玩具有一个三角形、一个圆形和一个长方形的袋子。那个包不太合身。你需要打开袋子,取出这3件物品,现在它们就可以了。Python*运算符执行此解包过程。

*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")


在Python 3.5中,您还可以在列表、字典、元组和集合显示(有时也称为文字)中使用此语法。参见PEP 488:其他解包概括。

>>> (0, *range(1, 4), 5, *range(6, 8))
(0, 1, 2, 3, 5, 6, 7)
>>> [0, *range(1, 4), 5, *range(6, 8)]
[0, 1, 2, 3, 5, 6, 7]
>>> {0, *range(1, 4), 5, *range(6, 8)}
{0, 1, 2, 3, 5, 6, 7}
>>> d = {'one': 1, 'two': 2, 'three': 3}
>>> e = {'six': 6, 'seven': 7}
>>> {'zero': 0, **d, 'five': 5, **e}
{'five': 5, 'seven': 7, 'two': 2, 'one': 1, 'three': 3, 'six': 6, 'zero': 0}

它还允许在单个函数调用中解包多个可迭代项。

>>> range(*[1, 10], *[2])
range(1, 10, 2)

(感谢mgilson提供PEP链接。)

单*表示可以有任意数量的额外位置参数。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}