具有星号参数和没有星号参数的函数调用的区别

16

我知道在Python函数定义中星号的意义。

但是我经常看到在带有参数的函数调用中使用星号,比如:

def foo(*args, **kwargs):
    first_func(args, kwargs)
    second_func(*args, **kwargs)

第一次和第二次函数调用有什么区别?


1
星号将变量从括号中取出 :) - LittleQ
可能是Python中理解kwargs的重复内容 - user559633
3个回答

24

args = [1,2,3]:

func(*args) == func(1,2,3) - 将变量从列表(或任何序列类型)中解包作为参数。

func(args) == func([1,2,3]) - 传递了整个列表。

kwargs = dict(a=1,b=2,c=3):

func(kwargs) == func({'a':1, 'b':2, 'c':3}) - 传递了整个字典。

func(*kwargs) == func(('a','b','c')) - 字典的键的元组(以随机顺序)被传递。

func(**kwargs) == func(a=1,b=2,c=3) -(键、值)从字典(或任何其他映射类型)中解包为命名参数。


一个好的简单回答。谢谢。 - Robert Moon
非常好的回答:+1!您能否添加并解释一下 func(*kwarg) 的用例? - winklerrr
太棒了,你解释得非常好。实际上这并不难,但很多人会写五页以上的内容来讲解它。 - Toskan

10

区别在于参数如何传递给被调用的函数。当您使用*时,参数将被解压缩(如果它们是列表或元组)—否则,它们会按原样传递。

以下是区别的示例:

>>> def add(a, b):
...   print a + b
...
>>> add(*[2,3])
5
>>> add([2,3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (1 given)
>>> add(4, 5)
9

当我在参数前加上*时,它实际上将列表解包为两个单独的参数,分别作为ab传递给add。如果没有加*,它只会将列表作为单个参数传递。

对于字典和**也是同样的情况,不同的是它们以命名参数而不是有序参数的形式传递。

>>> def show_two_stars(first, second='second', third='third'):
...    print "first: " + str(first)
...    print "second: " + str(second)
...    print "third: " + str(third)
>>> show_two_stars('a', 'b', 'c')
first: a
second: b
third: c
>>> show_two_stars(**{'second': 'hey', 'first': 'you'})
first: you
second: hey
third: third
>>> show_two_stars({'second': 'hey', 'first': 'you'})
first: {'second': 'hey', 'first': 'you'}
second: second
third: third

非常感谢您的详细回答。这对我非常有帮助。 - Robert Moon

0
def fun1(*args):
    """ This function accepts a non keyworded variable length argument as a parameter.
    """
    print args        
    print len(args)


>>> a = []

>>> fun1(a)
([],)
1
# This clearly shows that, the empty list itself is passed as a first argument. Since *args now contains one empty list as its first argument, so the length is 1
>>> fun1(*a)
()
0
# Here the empty list is unwrapped (elements are brought out as separate variable length arguments) and passed to the function. Since there is no element inside, the length of *args is 0
>>>

如果您在a中添加一些值,我认为您的答案会更清晰。 - winklerrr
那个例子是为了展示 args 解包的方式。如果将一个添加到'a'并传递给未解包的 args,则 args 的长度将为1。对于第一种情况,它将是(['some val'],),而对于第二种情况,它将是('some val',)。 - user2126456
如果您将之前评论中的示例添加到您的答案中,那就太棒了。 :-) - TrebledJ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接