>>> def foo1(*args, **kwargs):
... print(*args, **kwargs)
>>> def foo2(*args, **kwargs):
... print("{} {}".format(*args, **kwargs))
>> foo1(1)
1
>> foo2(1)
IndexError: tuple index out of range
Run Code Online (Sandbox Code Playgroud)
我的理解是否正确:*args, **kwargs实际上是一个元组,因为逗号使它成为一个,因为有两个占位符{},然后.format尝试访问该元组的第二个元素?
不,这不是真的,如果你的代码输出是真的"((1) {})",因为args它将是一个元组1和kwargs一个空的dict(表示为{}).
通常func(a,b)是调用具有两个参数的函数.这与使用元组func((a,b))调用函数不同,只使用单个参数调用此函数.
有时你想编写一个未知数量的参数的函数.您可以使用func(*args)(请注意,该名称args不是必需的,但是约定.前面有一个星号的任何名称都可以使用)语法来执行此操作.我们可以写一个join()函数,它不是一个字符串列表,而是一个任意数量的字符串作为参数:
def join_(*args):
rv = ""
for _string in args:
rv += _string
return(rv)
>>> join_("first", "second", "third")
"firstsecondthird"
>>> join_(["first", "second", "third"])
TypeError: Can't convert 'list' object to str implicitly
Run Code Online (Sandbox Code Playgroud)
正如您所看到的那样,您可以使用许多参数或参数列表(或者元组,因为这一点)来调用它.如果我们将它定义为def join_(args)第一个版本不会有效,但只有第二个.明星将"论证""吮吸"到一个列表中.你可以在这里找到文档.
如果有一种方法可以将参数提取到列表中,那么应该有一种方法可以将参数从列表中推送到函数参数中.而且有!(假设join_()从上面定义)
>>>join_(*["first", "second", "third"])
"firstsecondthird"
Run Code Online (Sandbox Code Playgroud)
因此,*在列表(或元组)前面会将列表的元素"推"出函数的参数.**是相同的,只是一个关键字参数的字典.
那么你的例子是做什么的?让我们来看看foo1.它将所有参数吸收到一个被调用的列表中args,然后再将这些参数推出到print函数中.所以你的foo1(1)来电print(1).怎么foo2办?您的呼叫foo2(1)呼叫print("{} {}".format(1))- 您要求替换值,但仅提供一个.另请注意,任何地方都没有元组.**kwargs怎么了?因为你没有指定关键字参数,所以它"消失了".它甚至不是一本空字典,因为您可以验证:
>>>print(**{})
>>>print({})
{}
Run Code Online (Sandbox Code Playgroud)
在另一个说明你可以做:
def foo3(*args, **kwargs):
print("{} {}".format(args, kwargs))
Run Code Online (Sandbox Code Playgroud)
永远不会引发异常:
>>> foo3()
() {}
>>> foo3("abc", "123")
('abc', '123') {}
>>>foo3("foo", c="bar")
('foo',) {'c': 'bar'}
Run Code Online (Sandbox Code Playgroud)