Introduction to the python decorator

  • 2020-04-02 14:24:31
  • OfStack

A decorator

The decorator design pattern allows you to dynamically wrap existing objects or functions to modify existing responsibilities and behavior, simply to dynamically extend existing functionality. This is essentially the concept of AOP in other languages, separating the true functionality of an object or function from other auxiliary functionality.

2. Decorators in Python

A decorator in python is typically a function that is entered and then decorated to return another function.   The more common functions are implemented using decorators, such as python's native staticmethod and classmethod.

Decorators come in two forms:


@A
def foo():
    pass

Is equivalent to:


def foo():
    pass
foo = A(foo)

The second one is with parameters:


@A(arg)
def foo():
    pass

Is equivalent to:


def foo():
    pass
foo = A(arg)(foo)

You can see that the first decorator is a function that returns a function, and the second decorator is a function that returns a function of a function.

Decorators in python can be used multiple times, as follows:


@A
@B
@C
def f (): pass
   
# it is same as below
def f(): pass
f = A(B(C(f)))

Third, decorator instances commonly used in Python

Decorators are often used to authenticate permissions before execution, log, or even modify incoming parameters, or preprocess returned results after execution, or even truncate the execution of functions, and so on.

Example 1:


from functools import wraps
def logged(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print (func.__name__() + " was called")
        return func(*args, **kwargs)
    return with_logging @logged
def f(x):
   """does some math"""
   return x + x * x print (f.__name__)  # prints 'f'
print (f.__doc__)   # prints 'does some math'

Note what the functools.wraps() function does: calling a decorated function is equivalent to calling a new function, and when you look at the function's arguments, comments, and even the name of the function, you only see the information about the decorator. The information about the wrapped function is thrown away. While wraps can help you to transfer the information, see http://stackoverflow.com/questions/308999/what-does-functools-wraps-do


Related articles: