In method call args, how to override keyword argument of unpacked dict?
You can use the built-in dict
type for that purpose. It accepts another dict as argument and additional key-value pairs as keyword arguments (which have precedence over the values in the other dict).
Thus you can create an updated dictionary via dict(template_vars, a=1)
.
You can unfold this dict as keyword arguments: func(**dict(...))
.
Like that there is no need to change the signature of your function and you can update/add as many key-value pairs as you want.
You can do it in one line like this:
func(**{**mymod.template_kvps, 'a': 3})
But this might not be obvious at first glance, but is as obvious as what you were doing before.
What I would suggest is having multiple templates (e.g. template_kvps_without_a
), but this would depend on your specific use case:
func(**mymod.template_kvps_without_a, a=3)
I'd consider function decorators as this keeps the syntax mostly the same as you requested. The implementation would look something like:
def combine(func):
def wrapper(*args, **kwargs):
fargs = {}
if args and isinstance( args[0], dict ):
fargs = args[0].copy()
fargs.update(kwargs)
return func(**fargs)
return wrapper
@combine
def funky(**kwargs):
for k,v in kwargs.iteritems():
print "%s: %s" % (k, v)
# All of these work as expected
funky( {'a': 1, 'b': 2}, a=3 )
funky( {'a': 1, 'b': 2} )
funky( a=3 )