繁体   English   中英

将 kwargs 显式传递给函数参数

[英]Pass kwargs to function argument explictly

Python 中有没有办法将字典显式传递给函数的**kwargs参数? 我正在使用的签名是:

def f(*, a=1, **kwargs): pass # same question with def f(a=1, **kwargs)

我试图通过以下方式调用它:

my_dict=dict(b=2)
f(kwargs=my_dict) # wrong, kwargs receives {'kwargs': {'b': 2}} instead of {'b': 2}
f(**kwargs=my_dict) # SyntaxError: invalid syntax
f(kwargs=**my_dict) # SyntaxError: invalid syntax

我想这样做的原因是我传入的字典可能包含键a ,我不希望它污染f的参数a

overlap_dict=dict(a=3,b=4)
f(**overlap_dict) # wrong, 'a' is 3, and 'kwargs' only contains 'b' key
f(a=2, **overlap_dict) # TypeError: f() got multiple values for keyword argument 'a'

f签名中的字典替换**kwargs对我来说不是一个选择。

a更新kwargs ,然后通过它。 例如,假设您有一个值a=1 ,然后这样做。

kwargs["a"] = a
f(**kwargs)

您可以临时(或永久,如果需要,只需删除最后一行)修改f以将kwargs作为关键字参数。 请注意,这是一个有点邪恶的 hack,所以我敦促您先尝试其他解决方法。

import inspect


def f(*, a=1, **kwargs):
    print(a)
    print(kwargs)


code = f.__code__
f.__code__ = code.replace(
    co_kwonlyargcount=code.co_kwonlyargcount + 1,
    co_flags=code.co_flags - inspect.CO_VARKEYWORDS,
)
f(kwargs={"a": 3, "b": 4})
f.__code__ = code

这打印:

1
{'a': 3, 'b': 4}

如果您不想更改f以接受更多参数,您可以简单地创建a列表,第一个条目是f ,第二个条目是kwargs ,例如:

def f(*, a, **kwargs):
    if len(a) == 1:
        a = a[0]
    elif len(a) == 2:
        kwargs['a'] = a[1]
        a = a[0]

你也可以用字典做类似的事情:

def f(*, a, **kwargs):
    if 'kwargs' in a.keys():
        kwargs['a'] = a['kwargs']
    a = a['f']

或者,这确实改变了f的参数输入,但我认为它更清晰一些。 我能想到的有2个案例。 首先,如果您知道a将始终设置在kwargs中:

def f(*, a, a2, **kwargs):
    kwargs['a'] = a2

另一种情况是,如果您希望a是否传递给kwargs是可选的:

def f(*, a, a2=None, pass_a=False, **kwargs):
    if pass_a:
        kwargs['a'] = a2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM