将 kwargs 显式传递给函数参数

发布于 2025-01-12 02:52:49 字数 875 浏览 0 评论 0原文

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签名对我来说不是一个选择。

Is there a way in Python to pass explicitly a dictionary to the **kwargs argument of a function? The signature that I'm using is:

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

I tried to call it the following ways:

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

The reason I want to do this is that the dictionary I pass in may contain the key a, and I don't want it to pollute the f's argument 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'

Replacing **kwargs with a dictionary in f's signature is not an option for me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

坐在坟头思考人生 2025-01-19 02:52:49

如果您不想更改 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

If you don't want to change f to accept more parameters, you could simply make a take a list and the first entry is for f, and the second entry is for kwargs, for instance:

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

You can also do something similar with a dictionary:

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

Alternatively, this does change f's parameter inputs, but I think it's a bit clearer. There are 2 cases I can think of. First, if you know that a will always be set in kwargs:

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

The other case is if you want it to be optional whether a passes to kwargs:

def f(*, a, a2=None, pass_a=False, **kwargs):
    if pass_a:
        kwargs['a'] = a2
一绘本一梦想 2025-01-19 02:52:49

a 更新 kwargs 并传递它。例如,假设您有一个值a=1,那么就这样做。

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

Update the kwargs with a and then pass it. Example, say you have a value a=1, then do like this.

kwargs["a"] = a
f(**kwargs)
挽袖吟 2025-01-19 02:52:49

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

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}

You can temporarily (or permanently, if you want – just remove the last line) modify f to take kwargs as a keyword argument. Note that this is a somewhat evil hack, so I would urge you to try other workarounds first.

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

This prints:

1
{'a': 3, 'b': 4}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文