装饰器
不带参数完整的装饰器
被装饰函数的基本信息变成了装饰器返回的 wrapper 函数的信息
用wraps将被装饰函数的信息复制给 wrapper 函数
from functools import wraps
import time
def timethis(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(func.__name__, end - start)
return result
return wrapper
@timethis
def fibonacci(n):
"""
求斐波拉契数列第 n 项的值
"""
a = b = 1
while n > 2:
a, b = b, a + b
n -= 1
return b
if __name__ == '__main__':
a=fibonacci(100)
print(a)
带参数完整的装饰器
返回一个装饰器,这个返回的装饰器再去装饰 func 函数
def logged(level, name=None, message=None):
def decorator(func):
logname = name if name else func.__module__
logmsg = message if message else func.__name__
@wraps(func)
def wrapper(*args, **kwargs):
print(level, logname, logmsg, sep=' - ')
return func(*args, **kwargs)
return wrapper
return decorator
@logged('debug', name='example', message='message')
def fun(*args, **kwargs):
pass
def main():
fun()
if __name__ == '__main__':
main()
多功能装饰器
多个装饰器,按靠近函数的先执行,fun前面的执行顺序相反,fun里的靠近函数执行
from functools import wraps, partial #partial函数作用:将所作用的函数作为partial()函数的第一个参数,原函数的各个参数依次作为partial()函数的后续参数 def logged(func=None, *, level='debug', name=None, message=None): if func is None: return partial(logged, level=level, name=name, message=message) logname = name if name else func.__module__ logmsg = message if message else func.__name__ @wraps(func) def wrapper(*args, **kwargs): print(level, logname, logmsg, sep=' - ') return func(*args, **kwargs) return wrapper @logged def func(*args, **kwargs): pass @logged(level='debug', name='example', message='message') def fun(*args, **kwargs): pass def main(): func()#有第一个参数值,不执行partial函数 fun()#无第一个参数值,执行partial函数 即 执行logged(func=fun(),level='debug', name='example', message='message') if __name__ == '__main__': main()