Is there a way to add key-value-pair into kwargs during the function call?
def f(**kwargs):
print(kwargs)
# ...
pre_defined_kwargs = {'a': 1, 'b': 2}
f(**pre_defined_kwargs, c=3)
Or even change the existing arguments?
f(**pre_defined_kwargs, b=3) # replaces the earlier b=2
These two examples don't work, as they raise error
>>> f(**pre_defined_kwargs, c=3)
SyntaxError: invalid syntax
Pointing at the comma in between the arguments
For Python versions < 3.5, you need to place the **kwargs
variable keyword argument last:
f(c=3, **pre_defined_kwargs)
See the Calls expression syntax; in all forms of the grammar the "**" expression
rule is placed last. In other words, using anything after the **expression
syntax is a syntax error.
If you want to update the dictionary with new values, you can use the dict()
callable; it can create a copy of your existing dictionary and update keys in that, provided the keys are also valid Python identifiers (start with a letter or underscore, and only contain letters, digits and underscores):
f(c=3, **dict(pre_defined_kwargs, b=42))
Here b=42
sets a new value for the 'b'
key. This same syntax can be used to add keys too, of course.
You cannot use the same key both in the **expression
mapping and explicitly; that'll raise a TypeError
. Again, from the documentation already linked:
If the syntax
**expression
appears in the function call,expression
must evaluate to a mapping, the contents of which are treated as additional keyword arguments. In the case of a keyword appearing in bothexpression
and as an explicit keyword argument, aTypeError
exception is raised.
Demo:
>>> 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}
This restriction has been lifted as of Python 3.5 (thanks to PEP-448 -- Additional Unpacking Generalizations; you can now freely mix the order of argument types and use multiple **mapping
references in a call (using distinct mappings). Keywords still have to be unique across all arguments applied; you still can't 'override' arguments that appear more than once.