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