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.
CodePudding user response:
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)
CodePudding user response:
Chage function defination to def f(a=1, /, **kwargs): pass
def f(a=1,/, **kwargs):
print(a)
print(kwargs)
overlap_dict=dict(a=3,b=4)
f(**overlap_dict)
# 1
# {'a': 3, 'b': 4}
CodePudding user response:
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}