Mapping Ordered Args to Keyword Args in Python
May 24th, 2009It’s been a while, so I thought I’d start off slow with a little tidbit I busted out today.
Here’s the problem:
Say I have
def foo(b, c):
...
and
def bar(a, b, c, *args, **kwargs):
...
and
def baz(*args, **kwargs):
...
And I want to write a decorator or something that intercepts the variable b before it hits the function.
How am I supposed to know which one is b when it’s different positions in each function, or could even be a kwarg?
I have my decorator right here:
from decorator import decorator
@decorator
def lol_dec(fn, *args, **kwargs):
...
I figured the best solution would be moving the args that could be named intoto the kwargs. It took me a bit of digging until I came across the inspect module, but it worked, and can work for you.
from inspect import getargspec
def fudge_args(fn, args, kwargs):
#TODO once we all use 2.6 change it to following
#fn_args = getargspec(fn).args
fn_args = getargspec(fn)[0]
new_kwargs = dict(zip(fn_args, args))
new_kwargs.update(kwargs)
return args[len(fn_args):], new_kwargs
It’s as easy as that. We just take the list of args from the ArgSpec, zip it up with the list of ordered arguments (args). Add them to a copy of kwargs. Note, we’re only returning args that were left over after the zip.
It’s used like so:
@decorator
def lol_dec(fn, *args, **kwargs):
args, kwargs = fudge_args(fn, args, kwargs)
kwargs['b'] = kwargs['b'] * 3
return fn(*args, **kwargs)










