I come from a background in static languages. Can someone explain (ideally through example) the real world advantages of using **kwargs over named arguments?
To me it only seems to make the function call more ambiguous. Thanks.
You may want to accept nearly-arbitrary named arguments for a series of reasons -- and that's what the **kw
form lets you do.
The most common reason is to pass the arguments right on to some other function you're wrapping (decorators are one case of this, but FAR from the only one!) -- in this case, **kw
loosens the coupling between wrapper and wrappee, as the wrapper doesn't have to know or care about all of the wrappee's arguments. Here's another, completely different reason:
d = dict(a=1, b=2, c=3, d=4)
if all the names had to be known in advance, then obviously this approach just couldn't exist, right? And btw, when applicable, I much prefer this way of making a dict whose keys are literal strings to:
d = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
simply because the latter is quite punctuation-heavy and hence less readable.
When none of the excellent reasons for accepting **kwargs
applies, then don't accept it: it's as simple as that. IOW, if there's no good reason to allow the caller to pass extra named args with arbitrary names, don't allow that to happen -- just avoid putting a **kw
form at the end of the function's signature in the def
statement.
As for using **kw
in a call, that lets you put together the exact set of named arguments that you must pass, each with corresponding values, in a dict, independently of a single call point, then use that dict at the single calling point. Compare:
if x: kw['x'] = x
if y: kw['y'] = y
f(**kw)
to:
if x:
if y:
f(x=x, y=y)
else:
f(x=x)
else:
if y:
f(y=y)
else:
f()
Even with just two possibilities (and of the very simplest kind!), the lack of **kw
is aleady making the second option absolutely untenable and intolerable -- just imagine how it plays out when there half a dozen possibilities, possibly in slightly richer interaction... without **kw
, life would be absolute hell under such circumstances!