A simple modification of @conmak's answer to still return a dictionary with None as values when the function has named arguments but no defaults:
def my_fn(a, b=2, c='a'):
pass
def get_defaults(fn):
### No arguments
if isinstance(fn.__code__.co_varnames, type(None)):
return {}
### no defaults
if isinstance(fn.__defaults__, type(None)):
return dict(zip(
fn.__code__.co_varnames,
[None]*(fn.__code__.co_argcount)
))
### every other case
return dict(zip(
fn.__code__.co_varnames,
[None]*(fn.__code__.co_argcount - len(fn.__defaults__)) + list(fn.__defaults__)
))
print(get_defaults(my_fn))
Should now give:
{'a': None, 'b': 2, 'c': 'a'}