Search notes:

Python: decorators

A decorator is a function with one parameter that takes a function and returns a function.
Such a decorator can be used to decorate a function with the following special syntax (called pie syntax):
@decoratorFunc
def F(…):
    …


F(…)
This is equivalent to
def decoratorFunc(func):
    …
    return callable

def F(…):
    …

F = decoratorFunc(F)

F(…)

Simple demonstration

The following simple script tries to demonstrate how a basic decorator is used:
def TQ84_decorator(func):

    print(f'TQ84_decorator was called for func {func.__name__}')

    def newFunc(*a, **kw):
        print(f'newFunc is calling {func.__name__}')
        func(*a, **kw)

    return newFunc


print('defining funcOne')

@TQ84_decorator
def funcOne():
    print(f'Within FuncOne')

print('defining funcTwo')

@TQ84_decorator
def funcTwo(p):
    print(f'Within FuncTwo, p = {p}')

print('calling  funcOne:')
funcOne()

print('calling  funcTwo:')
funcTwo(99)
Github repository about-Python, path: /functions/decorators/demo.py
When executed, it prints:
defining funcOne
TQ84_decorator was called for func funcOne
defining funcTwo
TQ84_decorator was called for func funcTwo
calling  funcOne:
newFunc is calling funcOne
Within FuncOne
calling  funcTwo:
newFunc is calling funcTwo
Within FuncTwo, p = 99

Parametrized decorator

It is possible to call a function that returns a decorator with the @function(…) syntax. Thus, it allows to create parametrized decorators.
In the following example, The function callMutliple(n) returns a decorator that calls a function n times. By using @callMutliple(5) on the fujnction F, F is executed 5 times when called:
def callMultiple(howMany):

    print(f'callMultiple({howMany})')

    def decorator(func):

        print(f'  decorator({func.__name__})')

        def caller(*a, **kw):
            print('   caller')
            for n in range(howMany):
                print(f'      n = {n}')
                func(*a, *kw) 

        return caller

    print('returning decorator')
    return decorator


print('Defining F')

@callMultiple(5)
def F(x):
    print(f'F: x = {x}')

print('Calling F')
F('foo')
Github repository about-Python, path: /functions/decorators/parametrized-decorator.py

See also

Built-in decorators are:

Index