Reputation: 45
I want to get a dictionary from a function that has the function arguments as keys and the default values as values.
I used inspect.getfullargspec()
to get a list of the argument and a list of the default values. Then I tried to use dict(zip())
to create a dictionary of those lists. This works, but only if every arguments has a default value. If one has no default, everything gets mixed up (as expected).
How can I for example if a argument has no default, add a None
as value.
Or any other ideas?
Here's the code:
def fn(name, age=18):
pass
spec = getfullargspec(fn)
args = spec.args
defaults = spec.defaults
zipped = dict(zip(args, defaults))
Upvotes: 3
Views: 805
Reputation: 45750
Since the non-default parameters must always be on the left (because non-defaulting parameters can't come after defaulting ones), you can calculate how much padding you need, then add that on to the front of the defaults:
def func(a, b=1, c=2, *args, **kwargs):
pass
spec = getfullargspec(func)
padded_defaults = (None,) * (len(spec.args) - len(spec.defaults)) + spec.defaults
zipped = dict(zip(spec.args, padded_defaults)) # {'a': None, 'b': 1, 'c': 2}
(len(spec.args) - len(spec.defaults))
calculates how much left padding is required then generates that padding using "sequence multiplication" ((None,) *
). + spec.defaults
then concatenates the padding onto the left of the existing defaults.
This may break in some corner case; although I can't think of such a case off-hand. This also isn't very efficient due to the tuple concatenation, but that's likely not an issue in 99% of cases.
There does not seem to be a mapping between arg->default stored anywhere, so it seems like your best bet is inferring what arguments have what defaults based on the number of each.
Upvotes: 3