from functools import wraps import time import logging def warn(timeout): def decorator(func): def wrapper(*args,**kargs): start = time.time() #记录返回值 res = func(*args,**kargs) used = time.time() - start if used > timeout: #超时则输入到日志中 msg = '"%s":%s > %s' % (func.__name__,used,timeout) logging.warn(msg) return res return wrapper return decorator from random import randint @warn(1.5) def test(): print('In test') while randint(0,1): time.sleep(0.5) for _ in range(30): print(test())
添加功能,动态修改timeout:
from functools import wraps import time import logging def warn(timeout): timeout = [timeout] #把timeout变成可变变量-列表,然后通过变量来修改 def decorator(func): def wrapper(*args,**kargs): start = time.time() #记录返回值 res = func(*args,**kargs) used = time.time() - start # if used > timeout: if used > timeout[0]: #超时则输入到日志中 msg = '"%s":%s > %s' % (func.__name__,used,timeout[0]) logging.warn(msg) return res # setTimeout做为wrapper的属性,通过函数调用setTimeout def setTimeout(k): # timeout是在闭包内使用的一个私有变量, nonlocal声明嵌套作用域的变量(py2不支持,也就无法修改timeout,不过可以将参数变为变量来修改) # nonlocal timeout # timeout = k timeout[0] = k wrapper.setTimeout = setTimeout return wrapper return decorator from random import randint @warn(1.5) def test(): print('In test') while randint(0,1): time.sleep(0.5) for _ in range(30): test() # 改成1s test.setTimeout(1) for _ in range(30): test()