Let me first admit that what I want to do can be considered something from stupid to evil, but I want to find out if I can do this in Python anyway.
Say I have a function decorator that accepts keyword arguments that define variables, and I want to access these variables in a wrapped function. I could do something like this:
def more_vars(**extras): def wrapper(f): @wraps(f) def wrapped(*args, **kwargs): return f(extras, *args, **kwargs) return wrapped return wrapper
Now I can do something like:
@more_vars(a='hello', b='world') def test(deco_vars, x, y): print(deco_vars['a'], deco_vars['b']) print(x, y) test(1, 2) # Output: # hello world # 1 2
What I don't like about this is that when you use this decorator, you need to change the signature of the function call by adding an additional variable in addition to the slap on the decorator. In addition, if you look at help for this function, you will see an additional variable that you do not expect to use when calling the function:
help(test)
This means that the user must call a function with 3 parameters, but obviously this will not work. Thus, you will also need to add a message to the docstring indicating that the first parameter is not part of the interface, it is just an implementation detail and should be ignored. However, this crappy one. Is there a way to do this without hanging these variables on something in a global scope? Ideally, I would like it to look like this:
@more_vars(a='hello', b='world') def test(x, y): print(a, b) print(x, y) test(1, 2) # Output: # hello world # 1 2 help(test) # Output: # Help on function test in module __main__: # # test(x, y)
I am only happy with the Python 3 solution if it exists.