摘錄整理于imooc
1. 一個帶參數(shù)的decorator
例子
例子是根據(jù) @performance('time_type')
攜帶的時間類型來輸出所裝飾的函數(shù)factorial
的執(zhí)行時間。
import time
import functools
from past.builtins.noniterators import reduce
def performance(unit):
def perf_decorator(f):
# @functools.wraps應(yīng)該作用在返回的新函數(shù)上摇肌。
@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.代參數(shù)的decorator
為什么要包三層(三階)擂红?
# 為什么包三層(三階)
@log('DEBUG')
def my_func():
pass
# 把上面的定義翻譯成高階函數(shù)的調(diào)用,就是:
my_func = log('DEBUG')(my_func)
# 上面的語句看上去還是比較繞围小,再展開一下:
log_decorator = log('DEBUG')
my_func = log_decorator(my_func)
# 上面的語句又相當(dāng)于:
log_decorator = log('DEBUG')
@log_decorator
def my_func():
pass
# 所以昵骤,帶參數(shù)的log函數(shù)首先返回一個decorator函數(shù),再讓這個decorator函數(shù)接收my_func并返回新函數(shù):
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())
簡而言之肯适,最外層負(fù)責(zé)把decorator
的參數(shù)DEBUG
傳進(jìn)來变秦,既然decorator
攜帶的參數(shù)已經(jīng)傳進(jìn)來,那么剩下的中間層和里層就是一個不帶參的decorator
的語法糖框舔。反之而推蹦玫,要多攜帶參數(shù),肯定是需要多加一階刘绣。