Parsing Args And Kwargs In Decorators
I've got a function that takes args and kwargs, and I need to do something in my decorator based on the value of the 2nd arg in the function, like in the code below: def workaround
Solution 1:
I found an answer using the python decorator
package. One feature of this package is that it preserves positional/keyword args no matter how the user passes them. It has the added benefit of reducing a lot of code, so my original code:
defworkaround_func():
defdecorator(fn):
defcase_decorator(*args, **kwargs):
if args[1] == 2:
print('The second argument is a 2!')
return fn(*args, **kwargs)
return case_decorator
return decorator
@workaround_func()defmy_func(arg1, arg2, kwarg1=None):
print('arg1: {} arg2: {}, kwargs: {}'.format(arg1, arg2, kwarg1))
becomes:
from decorator import decorator
@decoratordefworkaround_decorator(f, *args, **kwargs):
if args[1] == 2:
print('The second argument is 2!')
return f(*args, **kwargs)
@workaround_decoratordefmy_func(arg1, arg2, kwarg1=None):
print('arg1: {} arg2: {}, kwargs: {}'.format(arg1, arg2, kwarg1))
Solution 2:
This is the most robust way that I can think of to handle it... The trick is to inspect the name of the second argument. Then, in the decorator, you check to see if that name is present in kwargs
. If yes, then you use that. If no, then you use args
.
from inspect import getargspec
defdecorate(fn):
argspec = getargspec(fn)
second_argname = argspec[0][1]
definner(*args, **kwargs):
special_value = (kwargs[second_argname]
if second_argname in kwargs else args[1])
if special_value == 2:
print"foo"else:
print"no foo for you"return fn(*args, **kwargs)
return inner
@decoratedeffoo(a, b, c=3):
pass
foo(1,2,3)
foo(1,b=2,c=4)
foo(1,3,5)
foo(1,b=6,c=5)
running this results in:
foo
foo
no foo for you
no foo for you
as expected.
Post a Comment for "Parsing Args And Kwargs In Decorators"