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

def foo(x, y, *args):
def bar(x, y, **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])

其他回答

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

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

这个示例将帮助您立即记住Python中的*args、**kwargs甚至super和继承。

class base(object):
    def __init__(self, base_param):
        self.base_param = base_param


class child1(base): # inherited from base class
    def __init__(self, child_param, *args) # *args for non-keyword args
        self.child_param = child_param
        super(child1, self).__init__(*args) # call __init__ of the base class and initialize it with a NON-KEYWORD arg

class child2(base):
    def __init__(self, child_param, **kwargs):
        self.child_param = child_param
        super(child2, self).__init__(**kwargs) # call __init__ of the base class and initialize it with a KEYWORD arg

c1 = child1(1,0)
c2 = child2(1,base_param=0)
print c1.base_param # 0
print c1.child_param # 1
print c2.base_param # 0
print c2.child_param # 1

我想举一个别人没有提到的例子

*也可以打开发电机

Python3文档中的示例

x = [1, 2, 3]
y = [4, 5, 6]

unzip_x, unzip_y = zip(*zip(x, y))

unzip x将为(1,2,3),unzip y将为(4,5,6)

zip()接收多个iretable参数,并返回一个生成器。

zip(*zip(x,y)) -> zip((1, 4), (2, 5), (3, 6))

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)

上下文

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])