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

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

当前回答

从Python文档中:

如果位置参数多于形式参数槽,则会引发TypeError异常,除非存在使用语法“*identifier”的形式参数;在这种情况下,该形参接收包含多余位置参数的元组(如果没有多余位置参数,则为空元组)。如果任何关键字参数与正式参数名称不对应,则会引发TypeError异常,除非存在使用语法“**标识符”的正式参数;在这种情况下,该形参接收包含多余关键字参数的字典(使用关键字作为关键字,将参数值作为对应值),如果没有多余关键字参数,则接收(新的)空字典。

其他回答

此表便于在函数构造和函数调用中使用*和**:

            In function construction         In function call
=======================================================================
          |  def f(*args):                 |  def f(a, b):
*args     |      for arg in args:          |      return a + b
          |          print(arg)            |  args = (1, 2)
          |  f(1, 2)                       |  f(*args)
----------|--------------------------------|---------------------------
          |  def f(a, b):                  |  def f(a, b):
**kwargs  |      return a + b              |      return a + b
          |  def g(**kwargs):              |  kwargs = dict(a=1, b=2)
          |      return f(**kwargs)        |  f(**kwargs)
          |  g(a=1, b=2)                   |
-----------------------------------------------------------------------

这真的只是用来概括洛林·霍希斯坦的答案,但我觉得它很有用。

相关地:在Python 3中扩展了星形/splat运算符的用法

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


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)

*表示以元组形式接收变量参数

**表示接收变量参数作为字典

使用方式如下:

1) 单个*

def foo(*args):
    for arg in args:
        print(arg)

foo("two", 3)

输出:

two
3

2) 现在**

def bar(**kwargs):
    for key in kwargs:
        print(key, kwargs[key])

bar(dic1="two", dic2=3)

输出:

dic1 two
dic2 3

*args是一个特殊的参数,可以将0个或多个(位置)参数作为元组。**kwargs是一个特殊的参数,可以将0个或多个(关键字)参数作为字典。

*在Python中,有两种参数位置参数和关键字参数:

*参数:

例如,*args可以采用0个或多个参数作为元组,如下所示:

           ↓
def test(*args):
    print(args)

test() # Here
test(1, 2, 3, 4) # Here
test((1, 2, 3, 4)) # Here
test(*(1, 2, 3, 4)) # Here

输出:

()
(1, 2, 3, 4)
((1, 2, 3, 4),)
(1, 2, 3, 4)

并且,当打印*参数时,将打印4个数字,不带括号和逗号:

def test(*args):
    print(*args) # Here
 
test(1, 2, 3, 4)

输出:

1 2 3 4

并且,args具有元组类型:

def test(*args):
    print(type(args)) # Here
 
test(1, 2, 3, 4)

输出:

<class 'tuple'>

但是,*参数没有类型:

def test(*args):
    print(type(*args)) # Here
 
test(1, 2, 3, 4)

输出(错误):

TypeError:type()需要1或3个参数

并且,正常参数可以放在*args之前,如下所示:

          ↓     ↓
def test(num1, num2, *args):
    print(num1, num2, args)
    
test(1, 2, 3, 4)

输出:

1 2 (3, 4)

但是,**kwargs不能放在*args之前,如下所示:

             ↓     
def test(**kwargs, *args):
    print(kwargs, args)
    
test(num1=1, num2=2, 3, 4)

输出(错误):

语法错误:无效语法

而且,正常参数不能放在*args之后,如下所示:

                 ↓     ↓
def test(*args, num1, num2):
    print(args, num1, num2)
    
test(1, 2, 3, 4)

输出(错误):

TypeError:test()缺少2个必需的仅关键字参数:“num1”和“num2”

但是,如果正常参数具有默认值,则可以将它们放在*args之后,如下所示:

                      ↓         ↓
def test(*args, num1=100, num2=None):
    print(args, num1, num2)
    
test(1, 2, num1=3, num2=4)

输出:

(1, 2) 3 4

此外,**kwargs可以放在*args之后,如下所示:

                    ↓
def test(*args, **kwargs):
    print(args, kwargs)
    
test(1, 2, num1=3, num2=4)

输出:

(1, 2) {'num1': 3, 'num2': 4}

**克瓦格斯:

例如,**kwargs可以使用0个或多个参数作为字典,如下所示:

             ↓
def test(**kwargs):
    print(kwargs)

test() # Here
test(name="John", age=27) # Here
test(**{"name": "John", "age": 27}) # Here

输出:

{}
{'name': 'John', 'age': 27}
{'name': 'John', 'age': 27}

并且,当打印*kwargs时,将打印两个键:

def test(**kwargs):
    print(*kwargs) # Here
 
test(name="John", age=27)

输出:

name age

并且,kwargs具有dict类型:

def test(**kwargs):
    print(type(kwargs)) # Here
 
test(name="John", age=27)

输出:

<class 'dict'>

但是,*kwargs和**kwargs没有类型:

def test(**kwargs):
    print(type(*kwargs)) # Here
 
test(name="John", age=27)
def test(**kwargs):
    print(type(**kwargs)) # Here
 
test(name="John", age=27)

输出(错误):

TypeError:type()需要1或3个参数

并且,正常参数可以放在**kwargs之前,如下所示:

          ↓     ↓
def test(num1, num2, **kwargs):
    print(num1, num2, kwargs)

test(1, 2, name="John", age=27)

输出:

1 2 {'name': 'John', 'age': 27}

此外,*args可以放在**kwargs之前,如下所示:

           ↓
def test(*args, **kwargs):
    print(args, kwargs)

test(1, 2, name="John", age=27)

输出:

(1, 2) {'name': 'John', 'age': 27}

并且,正常参数和*args不能放在**kwargs之后,如下所示:

                    ↓     ↓
def test(**kwargs, num1, num2):
    print(kwargs, num1, num2)

test(name="John", age=27, 1, 2)
                     ↓
def test(**kwargs, *args):
    print(kwargs, args)

test(name="John", age=27, 1, 2)

输出(错误):

语法错误:无效语法

对于*args和**kwargs:

实际上,您可以为*args和**kwargs使用其他名称,如下所示*args和**kwargs通常使用:

            ↓        ↓
def test(*banana, **orange):
    print(banana, orange)
    
test(1, 2, num1=3, num2=4)

输出:

(1, 2) {'num1': 3, 'num2': 4}