Reputation: 965
Is there a way to send more kwargs into a function than is called for in the function call?
Example:
def mydef(a, b):
print a
print b
mydict = {'a' : 'foo', 'b' : 'bar'}
mydef(**mydict) # This works and prints 'foo' and 'bar'
mybigdict = {'a' : 'foo', 'b' : 'bar', 'c' : 'nooooo!'}
mydef(**mybigdict) # This blows up with a unexpected argument error
Is there any way to pass in mybigdict
without the error? 'c'
would never be used in mydef
in my ideal world and would just be ignored.
Thanks, my digging has not come up with what I am looking for.
Edit: Fixed the code a bit. The mydef(a, b, **kwargs)
was the form that I was looking for, but the inspect function args was a new thing to me and definitely something for my toolbox. Thanks everyone!
Upvotes: 12
Views: 6179
Reputation: 1121366
No, unless the function definition allows for more parameters (using the **kwargs
catch-all syntax), you cannot call a method with more arguments than it has defined.
You can introspect the function and remove any arguments it won't accept however:
import inspect
mybigdict = {'a2' : 'foo', 'b2' : 'bar', 'c2' : 'nooooo!'}
sig = inspect.signature(mydef)
if not any(p.kind == p.VAR_KEYWORD for p in sig.parameters.values()):
for missing in mybigdict.keys() - sig.parameters.keys():
del mybigdict[missing]
mydef(**mybigdict)
I'm using the inspect.signature()
function to check if the callable supports a **kwarg
catch-all (by looking for a Parameter.VAR_KEYWORD
entry), and if it doesn't, I use the set difference between mybigdict
and the signature .parameters
mapping to remove anything the method won't support.
Upvotes: 21
Reputation: 5888
To clarify Martijn Pieters's answer (for sake of clarity). It's possible if you change the function signature to:
def mydef(a, b, **kwargs):
This means it's not possible without changing the signature. But if that's not a problem it'll work.
Upvotes: 10