Python Decorators (similar to Java Annotations)

April 26, 2019
@ symbol

Why use Python Decorators

Python decorators is a wrapper around a python functions which allow you to

  • Validate the input arguments
  • Change the return result
  • Pass in additional input arguments
  • Perform open/lock before the function and close/unlock after the function
  • Allow you to execute code before and after the function
  • Conditionally execute the function

Basic Decorator

Add square bracket ([]) to the returned string.

from functools import wraps

def my_decorator(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
       return "[{0}]".format(f(*args, **kwargs))
    return wrapper

Test

@my_decorator
def hello(name):
    return f"Hello, {name}"

print(hello("Desmond"))

Output

[Hello, Desmond]

If you are sure of the fix named arguments of the target function, you can replace *args, **kwargs with actual named arguments:

from functools import wraps

def my_decorator(f):
    @wraps(f)
    def wrapper(name):
        return "[{0}]".format(f(name))
    return wrapper

Decorator with Arguments

def my_decorator(str_format):
    def decorator(f):
        @wraps(f)
        def wrapper(name):
            return str_format.format(f(name))
        '''
        def wrapper(*args, **kwargs):
            return str_format.format(f(*args, **kwargs))
        '''
        return wrapper
    return decorator

Usage: pass the str_format into arguments

@my_decorator("<{0}>")
def hello(name):
    return f"Hello, {name}"

Decorator pass arguments to function

Besides manipulating the returned result, you can pass in additional arguments into the target function.

This decorator pass an age arguments into the target function.

def my_decorator(str_format):
    def decorator(f):
        @wraps(f)
        def wrapper(name):
            return str_format.format(f(name, age=10))
        '''
        def wrapper(*args, **kwargs):
            return str_format.format(f(*args, **kwargs, age=10))
        '''
        return wrapper
    return decorator

Test

@my_decorator("<{0}>")
def hello(name, age):
    return f"Hello, {name}. I'm {age} years old."

print(hello("Desmond"))

Output

<Hello, Desmond. I'm 10 years old.>
This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.