Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manually calling a decorator that takes arguments

I have a function f1:

def f1():
  return True

I also have a decorator that takes arguments, that can be used like this:

@validate_arguments(arg1, arg2)

I am trying to call f1 manually without the @ (for testing and reuse purposes) but that doesn't seem to work.

So something like:

validate_arguments(f1, arg1, arg2)

The reason it does not work is because validate_arguments is a function that takes the arguments as parameters, and contains a closure that is the actual decorator.

Is there no way to do what I want? To manually call the decorator on a function without the @, for a decorator that takes arguments?

like image 289
darksky Avatar asked Jan 29 '14 19:01

darksky


People also ask

Can a Python decorator take argument?

Implementing Decorator Arguments You may expect that decorator arguments are somehow passed into the function along with this f argument, but sadly Python always passes the decorated function as a single argument to the decorator function.

Are decorators Pythonic?

Decorators are a very powerful and useful tool in Python since it allows programmers to modify the behaviour of a function or class. Decorators allow us to wrap another function in order to extend the behaviour of the wrapped function, without permanently modifying it.


1 Answers

You need something like:

def f1():
  return True
f1 = validate_arguments(arg1, arg2)(f1)

Here validate_arguments(arg1, arg2) returns the actual decorator, to that decorator we pass the function object f1, which in turn returns the new modified function.

Demo:

def validate_arguments(arg1, arg2):
    def decorator(func):
        def wrapped():
            print arg1, arg2
            return func()
        return wrapped
    return decorator

def f1():
  return True
f1 = validate_arguments(1, 2)(f1)
print f1()
#1 2
#True
like image 106
Ashwini Chaudhary Avatar answered Sep 19 '22 18:09

Ashwini Chaudhary