Question

Whenever I see a decorator in python, I always see it use at function definitions

def logger(func):
    def inner(*args, **kwargs): #1
        print "Arguments were: %s, %s" % (args, kwargs)
        return func(*args, **kwargs) #2
    return inner

@logger
def func(x, y=1):
    return x * y

func(2) # Returns Arguments were: (2,), {} \n 2

What would be an equivalent way to do what a decorator does at function definition, but allow you to invoke it at function call so that the function could be used with and without the "decorator"?

(Below is my hope, and though I don't think you could do it with a decorator, I am using the @ to show the idea)

def func(x, y=1):
    return x * y

func(2) # returns 2

@logger
func(2)  # Returns Arguments were: (2,), {} \n 2 
Was it helpful?

Solution

All the @logger decoration does is automatically pass func through logger whenever func is invoked. You can simulate this with:

logger(func)(2)

logger(func) creates and returns a new function which writes out the log message and then calls func. At this point you just have a function reference, which you can then invoke with the (2) at the end.

You could also create a reference to that new function so you don't have to wrap it with logger() each time.

f = logger(func)
f(2)
f(3)
f(4)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top