Python Decorator 3.0 and arguments to the decorator
decorator, python
Solution
In this case, you need to make your function return the decorator. (Anything can be solved by another level of indirection...)
from decorator import decorator
def substitute_args(arg_sub_dict):
@decorator
def wrapper(fun, arg):
new_arg = arg_sub_dict.get(arg, arg)
return fun(new_arg)
return wrapper
This means `substitute_args` isn't a decorator itself, it's a decorator factory. Here's the equivalent without the `decorator` module.
def substitute_args(arg_sub_dict):
def my_decorator(fun):
def wrapper(arg):
new_arg = arg_sub_dict.get(arg, arg)
return fun(new_arg)
# magic to update __name__, etc.
return wrapper
return my_decorator
Three levels deep isn't very convenient, but remember two of them are when the function is defined:
@substitute_args({}) # this function is called and return value is the decorator
def f(x):
return x
# that (anonymous) decorator is applied to f
Which is equivalent to:
def f(x):
return x
f = substitude_args({})(f) # notice the double call
Problem
I'm excited to see the latest version of the `decorator` python module (3.0). It looks a lot cleaner (e.g. the syntax is more sugary than ever) than previous iterations. However, it seems to have lousy support (e.g. "sour" syntax, to horribly stretch the metaphor) for decorators that take arguments themselves. Does anyone have a good example for how you'd cleanly do this using `decorator` 3.0? ``` def substitute_args(fun, arg_sub_dict): def wrapper(arg): new_arg = arg_sub_dict.get(arg, arg) return fun(new_arg) # some magic happens here to make sure that type signature, # __name__, __doc__, etc. of wrapper matches fun return wrapper ```