Applying a decorator to an imported function?

killajoule picture killajoule · Sep 14, 2014 · Viewed 10k times · Source

I want to import a function:

from random import randint

and then apply a decorator to it:

@decorator
randint

I was wondering if there was some syntactic sugar for this (like what I have above), or do I have to do it as follows:

@decorator
def randintWrapper(*args):
    return random.randint(*args)

Answer

Martijn Pieters picture Martijn Pieters · Sep 14, 2014

Decorators are just syntactic sugar to replace a function object with a decorated version, where decorating is just calling (passing in the original function object). In other words, the syntax:

@decorator_expression
def function_name():
    # function body

roughly(*) translates to:

def function_name():
    # function body
function_name = decorator_expression(function_name)

In your case, you can apply your decorator manually instead:

from random import randint

randint = decorator(randint)

(*) When using @<decorator> on a function or class, the result of the def or class definition is not bound (assigned to their name in the current namespace) first. The decorator is passed the object directly from the stack, and only the result of the decorator call is then bound.