装饰器decorator
字面意思,给现有的函数添加一个装饰的功能
import time
def statistics_time(func):
'''统计函数运行时间的装饰器'''
def wrapper():
start_time = time.time()
func()
end_time = time.time()
total_time = end_time - start_time
print(f'{func.__name__} used {total_time}')
return wrapper
python的语法糖
@statistics_time
def f():
print('Hello world!')
@statistics_time放到f()的定义处,相当于执行 f = statistics_time(f)
还有一种带参数的装饰器,只需要给wrapper加上参数
import time
def statistics_time(func):
'''统计函数运行时间的装饰器‘’‘
def wrapper(*args, **kwargs):
start_time = time.time()
func(*args, **kwargs)
end_time = time.time()
total_time = end_time - start_time
print(f'{func.__name__} used {total_time}')
return wrapper
但是使用装饰器的同时会改变函数的__name__属性,执行依赖函数签名的代码就会出错
python内置的functools.wraps可以解决这个问题
下面是一个自动打印日志的装饰器
def debug(func):
def wrapper_debug(*args, **kwargs):
print(f'{func.__name__}:{args}, {kwargs}')
ret_val = func(*args, **kwargs)
print(f'return: {ret_val}')
return ret_val
return wrapper_debug
@debug
def add(a, b):
return a + b
add(1, 3)
一个函数还可以同时有多个装饰器