字典解包运算符 **

Dictionary Unpacking Operator **

为什么在 python 中使用这行代码会出现错误:

required, *args, **kwargs = "Welcome to...", 1, 2, 3, site='whosebug.com'
                 ^
                 SyntaxError: invalid syntax

在函数签名中使用它是可以的,例如:

def function1(required, *args, **kwargs):
    pass

function1("Welcome to...", 1, 2, 3, site='whosebug.com')

Python 不允许像 JavaScript 那样进行解构(我假设您有这方面的背景知识)。函数签名很特殊,它允许可变数量的参数——如果没有语法,您需要指定所有参数并将它们默认设置为 None。 *args(对于位置参数)和 **kargs(对于关键字参数)允许使用所有参数作为列表(或关键字参数的字典)。

Python只能析构元组,所以只有下面的代码有效。

first_param, second_param, third_param = "Welcome to...", 1, 2

您甚至可以用一个星号代替多个值,但它只能出现一次

first_param, *rest, last_param = "Welcome to...", 1, 2, 3

此外,您需要销毁整个元组,因此以下代码无效,将在运行时失败。

first_param, second_param = "Welcome to...", 1, 2

site='whosebug.com' 可能 作为关键字参数。

def function1(param1=1, param2=2):
    pass

function1(param2='hello')

这是您可以使用此语法的唯一情况。

我的猜测是因为如果我们想让这个 **kwargs 工作,我们必须在右侧有关键字参数(它应该被转换成字典)就像你做的那样:

required, *args, **kwargs = "Welcome to...", 1, 2, 3, site='whosebug.com'

但正如我们所知,首先评估赋值的右侧(然后进行解包)。所以在这种情况下,您可以在无效的表达式中考虑另一个赋值。例如:

a = (1, 2, 3)       # Valid
b = (1, 2, var=20)  # Invalid

通过查看:

from dis import dis
dis('a, b, c = 5, 4, 3')


  1           0 LOAD_CONST               0 ((5, 4, 3))
              2 UNPACK_SEQUENCE          3
              4 STORE_NAME               0 (a)
              6 STORE_NAME               1 (b)
              8 STORE_NAME               2 (c)
             10 LOAD_CONST               1 (None)
             12 RETURN_VALUE

Python 尝试从赋值的右侧构建一个元组,其中不能有赋值语句。我认为同样的事情发生了,这就是原因。

required, *args, **kwargs = "Welcome to...", 1, 2, 3, site='whosebug.com'
                 ^

像这样的星号通常在展开式中放在最后,尤其是函数调用或函数参数说明。此外,您不能以这种方式分配给它。

[*prefix, 2, 3, 4, *mid, 5, *suffix]

某些复杂对象类型(例如列表、上面和字典)的文字形式允许在表达式中的任何点使用星号进行扩展,在某种程度上函数调用也可以。在 参数规范 中,您声明需要“无限信息”,这些符号具有额外的含义和后果。

def foo(bar, *baz, diz): ...

diz 现在只是名称,不能按位置传递。没有默认值,它现在是一个 必需的 命名参数。因为能够将参数声明为仅限关键字实际上非常有用,并且接受额外的位置参数并将其填充到未使用的变量中有点反模式,PEP 3102 — Keyword-Only Arguments was written up and accepted to formalize using just a *, bare, to specify "everything after this point is keyword only". Additionally, there is a / marker to denote the separation between positional-only, and positional-or-keyword: the reverse. Reference.

归结为:文字扩展符号和参数规范符号意味着和做不同的事情。