标签:
decorator本身是一个函数,这个函数的功能是接受被修饰的函数(decorated)作为参数,返回包装函数(wrapper)替换被修饰函数(decorated)。
@decorator
func
等同于 func = decorator(func)
。大部分情况下wrapper函数必须要和decorated函数具有相同的参数,这样在wrapper函数中可以执行decorated函数,并增加一些拓展流程。基于此decorator的原则如下:
decorator接受目标函数为参数,并返回wrapper函数,因此不能接受额外的参数。为了传送额外的参数给decorator函数,可以创建decorator maker函数接受参数并返回decorator函数,然后使用decorator完成函数替换,将目标函数替换为wrapper函数。
示例:
def mydecorator_maker(*args, **kwargs):
print ‘this is decorator maker function... with args %s, kwargs %s‘ % (args, kwargs)
def mydecorator(func):
print ‘this is decorator... with args %s, kwargs %s‘ % (args, kwargs)
def decorator_wrapper(func_arg1, func_arg2):
print ‘this is decorator wrapper, before function... with arg1 %s, arg2 %s‘ % (func_arg1, func_arg2)
func(func_arg1, func_arg2)
print "this is decorator wrapper, after function"
return decorator_wrapper
return mydecorator
@mydecorator_maker(1, 2, 3, test=‘test‘)
def mydecorated_function(func_arg1, func_arg2):
print ‘this is decorated function with arg1 %s, arg2 %s‘ % (func_arg1, func_arg2)
mydecorated_function(‘lily‘, ‘Baby‘)
output:
this is decorator maker function... with args (1, 2, 3), kwargs {‘test‘: ‘test‘}
this is decorator... with args (1, 2, 3), kwargs {‘test‘: ‘test‘}
this is decorator wrapper, before function... with arg1 lily, arg2 Baby
this is decorated function with arg1 lily, arg2 Baby
this is decorator wrapper, after function
this is decorator maker function...
这种通过一个maker函数来接受额外的参数,并且做一些额外参数的处理的实现方式非常简明。拓展一下,因为decorator的函数替换的特点,可以对decorator函数进行一次decorator来实现额外参数的处理。首先梳理一下实现逻辑:
这种参数的变换不一致和上述wrapper参数保持一致的原则有悖,但是依然符合decorator进行函数替换的基本功能设计。
示例:
def decorator_decorator(decorator_to_decorated):
print ‘This decorator decorator will decorate decorator passed in...‘
print ‘passed in decorator is %s ‘ % decorator_to_decorated
def decorator_wrapper(*args, **kwargs):
print ‘decorator wrapper do something with args %s, kwargs %s...‘ % (args, kwargs)
return decorator_to_decorated
return decorator_wrapper
@decorator_decorator
def decorated_decorator(func):
print ‘func %s is decorated here‘ % func
def wrapper(func_arg1, func_arg2):
print ‘wrapper with arg1 %s, args2 %s‘ % (func_arg1, func_arg2)
return func(func_arg1, func_arg2)
return wrapper
@decorated_decorator(1, 2, 3, test=‘test‘)
def decorated_function(func_arg1, func_arg2):
print ‘decorated function with func arg1 %s, arg2 %s‘ % (func_arg1, func_arg2)
print ‘do something in decorated function‘
decorated_function(‘Liliy‘, ‘Baby‘)
output:
This decorator decorator will decorate decorator passed in...
passed in decorator is <function decorateddecorator at 0x111a99c80>
decorator wrapper do something with args (1, 2, 3), kwargs {‘test‘: ‘test‘}...
func <function decoratedfunction at 0x111b2bc08> is decorated here
wrapper with arg1 Liliy, args2 Baby
decorated function with func arg1 Liliy, arg2 Baby
do something in decorated function
标签:
原文地址:http://www.cnblogs.com/3days/p/5302832.html