Skip to content

Python decorators usage and example

A decorator takes a function, extends it and returns.

Simple example

def hello(func):
    def inner():
        print("Hello ")
        func()
    return inner

def name():
    print("Alice")

obj = hello(name)
obj()

In the above example, hello() is a decorator. the function name() is decorated by the function hello(). It wraps the function in the other function.

Syntactic sugar

@hello
def name():
    print("Alice")

if __name__ == "__main__":
    name()

Decorated function with arguments

def pretty_sumab(func):
    def inner(a,b):
        print(str(a) + " + " + str(b) + " is ", end="")
        return func(a,b)

    return inner

@pretty_sumab
def sumab(a,b):
    summed = a + b
    print(summed)

if __name__ == "__main__":
    sumab(5,3)

More general case

def use_logging(level):
    def decorator(func):
        def wrapper(*args, **kwargs):
            if level == "warn":
                logging.warn("%s is running" % func.__name__)
            elif level == "info":
                logging.info("%s is running" % func.__name__)
            return func(*args)
        return wrapper

    return decorator

@use_logging(level="warn")
def foo(name='foo'):
    print("i am %s" % name)

if __name__ == "__main__":
    foo()

Decorator with arguments

def simple(type_):

    def wrapper(func):
        def decorate(test_, redis_):
            print("[Decorate %s] %s, %s" % (type_, test_, redis_))
            return func(test_, redis_)

        return decorate

    return wrapper


@simple("get")
def t_get(t, r):
    print("GET %s, %s" % (t, r))


@simple("set")
def t_set(t, r):
    print("SET %s, %s" % (t, r))


if __name__ == '__main__':
    t_get("aa", "bb")
    t_set("cc", "dd")

Class decorator

class Foo(object):
    def __init__(self, func):
        self._func = func

    def __call__(self):
        print ('class decorator runing')
        self._func()
        print ('class decorator ending')

@Foo
def bar():
    print ('bar')

if __name__ == "__main__":
    bar()

Decorator order

@a
@b
@c
def f ():
    pass

## euqals to 

f = a(b(c(f)))

Using wrapt

import wrapt

def with_arguments(myarg1, myarg2):
    @wrapt.decorator
    def wrapper(wrapped, instance, args, kwargs):
        return wrapped(*args, **kwargs)
    return wrapper

@with_arguments(1, 2)
def function():
    pass

if __name__ == "__main__":
    function()

Using decorator

#!/usr/bin/env python
from decorator import decorate
from datetime import datetime

def wrapper(func, *args, **kwargs):
    """print log before a function."""
    print("[DEBUG] {}: enter {}()".format(datetime.now(), func.__name__))
    return func(*args, **kwargs)

def logging(func):
    return decorate(func, wrapper)

@logging
def foo(name='foo'):
    print("i am %s" % name)

if __name__ == "__main__":
    foo()

Reference

  • https://pythonbasics.org/decorators
  • https://wrapt.readthedocs.io/en/latest/quick-start.html
  • https://foofish.net/python-decorator.html

Disclaimer
  1. License under CC BY-NC 4.0
  2. Copyright issue feedback me#imzye.me, replace # with @
  3. Not all the commands and scripts are tested in production environment, use at your own risk
  4. No privacy information is collected here
Try iOS App