摘录整理于imooc
- 一个带参数的
decorator
例子
- 代参数的
decorator
为什么要包三层(三阶)?
1. 一个带参数的decorator
例子
例子是根据 @performance('time_type')
携带的时间类型来输出所装饰的函数factorial
的执行时间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import time import functools from past.builtins.noniterators import reduce
def performance(unit): def perf_decorator(f): @functools.wraps(f) def wrapper(*args, **kw): t1 = time.time() r = f(*args, **kw) t2 = time.time() t = (t2 - t1) * 1000 if unit == 'ms' else (t2 - t1) print('call %s() in %f %s' % (f.__name__, t, unit)) return r return wrapper return perf_decorator
@performance('ms') def factorial(n): return reduce(lambda x, y: x * y, range(1, n + 1))
factorial(10000) print(factorial.__name__)
|
2.代参数的decorator
为什么要包三层(三阶)?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| @log('DEBUG') def my_func(): pass
my_func = log('DEBUG')(my_func)
log_decorator = log('DEBUG') my_func = log_decorator(my_func)
log_decorator = log('DEBUG') @log_decorator def my_func(): pass
def log(prefix): def log_decorator(f): def wrapper(*args, **kw): print('[%s] %s()...' % (prefix, f.__name__)) return f(*args, **kw) return wrapper return log_decorator
@log('DEBUG') def test(): pass print(test())
|
简而言之,最外层负责把decorator
的参数DEBUG
传进来,既然decorator
携带的参数已经传进来,那么剩下的中间层和里层就是一个不带参的decorator
的语法糖。反之而推,要多携带参数,肯定是需要多加一阶。