Search code examples
pythonfunctiondecoratorpython-decorators

How can I apply a decorator to an imported function?


Suppose I have imported a function:

from random import randint

and then want to apply a decorator to it. Is there some syntactic sugar for this, perhaps something like so?

@decorator
randint

Or do I have create a wrapper function to decorate, like so?

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

Solution

  • 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.