Details of decorators in python

  • 2020-05-09 18:46:22
  • OfStack

Before understanding the decorator 1 must first understand the function as a parameter to pass, what is the function embedded, please refer to the blog I wrote before the function introduction

Because in python, function and object, also can be passed as a parameter. python decorator nature also is one kind of special function, it receives the parameter is a function object, and then add additional functionality dynamically function parameters, without having to modify the original function objects. python decorator incoming parameter is a function, the return value is also a function!
The idea of the python decorator is somewhat similar to the decorator pattern of the design pattern, which is intended to dynamically add additional functionality to the function object, such as the ability to add log printing, with a bit of an aspect oriented programming (AOP) feel.
Decorator grammar

Begins with @, followed by the name of the decorator and optional parameters. The decorator syntax is a syntactic sugar.
Format is as follows


@decomaker(deco_args)
    def foo(func_opt_args)

It can be combined, which is equivalent to foo = g(f(foo)).

@g
@f
def foo():
    statement

Simple decorator

The instance


#!/usr/bin/python
def  deco(func):
    print 'start'
    func()
    print 'end'
    return func @deco
def foo():
    print 'In foo' foo()
foo()

The output

start
In foo
end
In foo
In foo

Decorator with built-in functions

Inline functions ensure that new functions are called each time. And decorated functions can take arguments.
The instance


def  deco(func):
    def _deco(x):    # This function is inline
        print 'start'
        func(x)
        print 'end'
    return _deco @deco
def foo(x):
    print 'In foo, get value is: %d' % x foo(123456)

Output:

start
In foo, get value is: 123456
end

Parameter decorator

You need to return your own decorator that takes a function as an argument. In other words,decomaker() does something with deco_args and returns the function object, which is the decorator that takes foo as its argument. Simply put :foo=decomaker(deco_args)(foo)

The instance


def deco(arg):
    def wrapper1(func):
        def _deco(x):
            print "get type is: ", arg
            func(x)
        return _deco     def wrapper2(func):
        def _deco(x):
            func(x)
            print "get type is: ", arg
        return _deco     if arg == 'type1':
        return wrapper1
    else:
        return wrapper2 @deco("type2")
def foo(x):
    print 'In foo: ', x foo(123)

The output

In foo:  123
get type is:  type2

conclusion

Decorator essence is a function of high order, can decorate other function, increasing the function of the decorative function, but cannot be decorative function coverage or change the original behavior. For be decorative function, a decorator is transparent. Decorators incoming parameters for function, return functions are decorated. Finally, we add a function to achieve print log function, without having to change the function.


#!/usr/bin/python
#coding=utf-8
import functools def log(prefix, suffix):
    def deco(func):
        @functools.wraps(func)
        def wrapper(*args, **kargs):
            print '%s log start' % prefix
            print('get a is: %s' % args[0])
            print('get b is: %s' % args[1])
            print('get c is: %s' % args[2])
            print('get d is: %s' % kargs['d'])
            print('get d is: %s' % kargs['f'])
            func(*args, **kargs)
            print '%s log end' % suffix
        return wrapper
    return deco @log('logstart', 'logend')
def test(a, b, c, d, f):
    print 'call func name is: %s' % test.__name__ test(1, 2, 3, d = 'dddd', f = 'ffff')

Output:

logstart log start
get a is: 1
get b is: 2
get c is: 3
get d is: dddd
get d is: ffff
call func name is: test
logend log end


Related articles: