Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create dictionary from/with function arguments as keys and default values as value

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))
like image 893
aaronlyy Avatar asked Feb 23 '26 22:02

aaronlyy


1 Answers

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.

like image 142
Carcigenicate Avatar answered Feb 26 '26 13:02

Carcigenicate