Chapter 9 Decorator

9.1 Definition

  • Decorator is a function that accept callable as the only argument
  • The main purpose of decarator is to enhance the program of the decorated function
  • It returns a callable

9.2 Examples

9.2.1 Example 1 - Plain decorator function

  • Many times, it is useful to register a function elsewhere - for example, registering a task in a task runner, or a functin with signal handler
  • register is a decarator, it accept decorated as the only argument
  • foo() and bar() are the decorated function of register
registry = []

def register(decorated):
    registry.append(decorated)
    return decorated

@register
def foo():
    return 3

@register
def bar():
    return 5
registry
## [<function foo at 0x0000029E803F8700>, <function bar at 0x0000029E804375E0>]
registry[0]()
## 3
registry[1]()
## 5

9.2.2 Example 2 - Decorator with Class

  • Extending the use case above
  • register is the decarator, it has only one argument
class Registry(object):
    def __init__(self):
        self._functions = []
    def register(self,decorated):
        self._functions.append(decorated)
        return decorated
    def run_all(self,*args,**kwargs):
        return_values = []
        for func in self._functions:
            return_values.append(func(*args,**kwargs))
        return return_values

The decorator will decorate two functions, for both object a and b

a = Registry()
b = Registry()

@a.register
def foo(x=3):
    return x

@b.register
def bar(x=5):
    return x

@a.register
@b.register
def bax(x=7):
    return x

Observe the result

print (a._functions)
## [<function foo at 0x0000029E80437670>, <function bax at 0x0000029E80437940>]
print (b._functions)
## [<function bar at 0x0000029E804378B0>, <function bax at 0x0000029E80437940>]
print (a.run_all())
## [3, 7]
print (b.run_all())
## [5, 7]
print ( a.run_all(x=9) )
## [9, 9]
print ( b.run_all(x=9) )
## [9, 9]