在函数调用期间向kwargs添加参数?

Mar*_*nen 17 python kwargs keyword-argument python-3.x

有没有办法在函数调用期间将键值对添加到kwargs中?

def f(**kwargs):
    print(kwargs)

# ...

pre_defined_kwargs = {'a': 1, 'b': 2}

f(**pre_defined_kwargs, c=3)
Run Code Online (Sandbox Code Playgroud)

甚至改变现有的论点?

f(**pre_defined_kwargs, b=3)  # replaces the earlier b=2
Run Code Online (Sandbox Code Playgroud)

这两个例子不起作用,因为它们会引起错误

>>> f(**pre_defined_kwargs, c=3)
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)

指着论点之间的逗号

Mar*_*ers 32

对于Python版本<3.5,您需要将**kwargs变量关键字参数放在最后:

f(c=3, **pre_defined_kwargs)
Run Code Online (Sandbox Code Playgroud)

请参阅Calls表达式语法 ; 在所有形式的语法中,"**" expression规则最后放置.换句话说,在**expression语法之后使用任何东西都是语法错误.

如果要使用新值更新字典,可以使用dict()callable ; 如果密钥也是有效的Python标识符(以字母或下划线开头,并且只包含字母,数字和下划线),它可以创建现有字典的副本更新密钥:

f(c=3, **dict(pre_defined_kwargs, b=42))
Run Code Online (Sandbox Code Playgroud)

这里为键b=42设置了一个'b'.当然,也可以使用相同的语法来添加键.

您不能在**expression映射和显式中使用相同的密钥; 这会引发一场TypeError.再次,从已经链接的文档:

如果语法**expression出现在函数调用中,则expression必须求值为映射,其内容将被视为附加关键字参数.如果关键字出现在两者中expression并且作为显式关键字参数出现,TypeError则会引发异常.

演示:

>>> def f(**kwargs):
...     print(kwargs)
... 
>>> pre_defined_kwargs = {'a': 1, 'b': 2}
>>> f(c=3, **pre_defined_kwargs)
{'a': 1, 'c': 3, 'b': 2}
>>> dict(pre_defined_kwargs, b=42)
{'a': 1, 'b': 42}
>>> f(c=3, **dict(pre_defined_kwargs, b=42))
{'a': 1, 'c': 3, 'b': 42}
Run Code Online (Sandbox Code Playgroud)

从Python 3.5开始,这个限制已经解除了(感谢PEP-448 - 附加解包概括 ;你现在可以自由地混合参数类型的顺序并**mapping在调用中使用多个引用(使用不同的映射).关键字仍然必须是唯一的应用所有参数;您仍然无法"覆盖"多次出现的参数.