Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

access function arguments from function decorator

Tags:

python

If I have a function that looks like:

@app.route('/categories/id/<int:id>/edit')
@login_required
def edit_category(id):
   #some code...

And the login_required decorator looks like this

def login_required(f):
   @wraps(f)
   def wrapper(*args, **kwargs):
       print id #given to edit_category by app.route decorator
       return f(*args, **kwargs)
   return wrapper

How do I access the id variable that is given to edit_category as an argument by the app.route decorator, from the login_required decorator?

like image 410
Adam Van Oijen Avatar asked Sep 08 '15 03:09

Adam Van Oijen


People also ask

How do I get past the Kwargs to decorator?

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 .

How do you pass arguments in decorator functions in Python?

To fix this, you need to change the repeat decorator so that it accepts an argument that specifies the number of times a function should execute like this: @repeat(5) def say(message): ... To define the repeat decorator, the repeat(5) should return the original decorator. The new repeat function returns a decorator.

Can functions take functions as arguments?

Because functions are objects we can pass them as arguments to other functions. Functions that can accept other functions as arguments are also called higher-order functions.

Can decorator take argument?

The decorator arguments are accessible to the inner decorator through a closure, exactly like how the wrapped() inner function can access f . And since closures extend to all the levels of inner functions, arg is also accessible from within wrapped() if necessary.


1 Answers

The positional arguments to the wrapper function come in the args (first argument - *args ) , and the keyword arguments for the method come in kwargs (second argument - **kwargs ).

args is a tuple , where the first element refers to the first positional argument, second element is the second positional argument.

kwargs is a dictionary , where the key is the keyword (for the argument) and the value is the value passed in for that keyword.

Example -

>>> def decor(func):
...     def wrapper(*args, **kwargs):
...             print('args - ',args)
...             print('kwargs - ',kwargs)
...             return func(*args, **kwargs)
...     return wrapper
...
>>> @decor
... def a(*a, **b):
...     print("In a")
...     print(a)
...     print(b)
...
>>> a(1,2,x=10,y=20)
args -  (1, 2)
kwargs -  {'y': 20, 'x': 10}
In a
(1, 2)
{'y': 20, 'x': 10}

You can test whether app.route is sending id as positional argument or keyword argument by printing both args and kwargs and take the correct value. I think it may be coming in as positional argument, if so, it would be the first element of args .

like image 197
Anand S Kumar Avatar answered Sep 20 '22 05:09

Anand S Kumar