摘录整理于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的语法糖。反之而推,要多携带参数,肯定是需要多加一阶。