python中元组解包的语义

use*_*424 28 python tuples iterable-unpacking

为什么python只允许命名参数跟随函数调用中的元组解包表达式?

>>> def f(a,b,c):
...     print a, b, c
... 
>>> f(*(1,2),3)
  File "<stdin>", line 1
SyntaxError: only named arguments may follow *expression
Run Code Online (Sandbox Code Playgroud)

它只是一种美学选择,还是存在允许这会导致一些含糊不清的情况?

and*_*oke 29

我很确定人们"自然地"不喜欢这个的原因是因为它使得后面的参数的含义模糊不清,这取决于插值系列的长度:

def dangerbaby(a, b, *c):
    hug(a)
    kill(b) 

>>> dangerbaby('puppy', 'bug')
killed bug
>>> cuddles = ['puppy']
>>> dangerbaby(*cuddles, 'bug')
killed bug
>>> cuddles.append('kitten')
>>> dangerbaby(*cuddles, 'bug')
killed kitten
Run Code Online (Sandbox Code Playgroud)

你不能只看到最后两个电话,dangerbaby哪个按预期工作,哪一个杀死小猫蓬松金属.

当然,在最后插值时也存在一些不确定性.但混淆受限于插值序列 - 它不会影响其他参数,例如bug.

[我快速搜索,看看我是否能找到任何正式的东西.似乎varags的*前缀是在python 0.9.8引入的.这里讨论了以前的语法,它的工作原理相当复杂.因为在没有*标记的情况下添加额外的参数"必须"发生在最后,似乎只是简单地延续了.最后在这里提到了一个关于参数列表的长时间讨论,而不是通过电子邮件.


ale*_*xis 6

我怀疑这是为了与函数定义中的星号表示法保持一致,这是函数调用中星号表示法的所有模型.

在下面的定义中,参数*c将覆盖所有后续的非关键字参数,因此很明显,在f调用时,传递值的唯一方法d是作为关键字参数.

def f(a, b, *c, d=1):
    print "slurped", len(c)
Run Code Online (Sandbox Code Playgroud)

(这种"唯一关键字参数"在Python 3只支持在Python 2存在没有办法星号的参数后,分配值,所以上述是非法的.)

因此,在函数定义中,加星标的参数必须遵循所有普通的位置参数.您观察到的是,相同的规则已扩展到函数调用.这样,星形语法对于函数声明和函数调用是一致的.

另一个并行性是在函数调用中只能有一个(单个)星号参数.以下是非法的,但很容易想象它被允许.

f(*(1,2), *(3,4))
Run Code Online (Sandbox Code Playgroud)