【笔记】如何实现属性可修改的函数装饰器
为分析程序内哪些函数执行时间开销较大,我们定义一个带timeout参数的函数装饰器。功能如下:
1、统计被装饰函数单词调用运行时间
2、时间大于参数timeout的,将此次函数调用记录到log日志中
3、运行时可修改timeout的值
方法:为包裹增添一个函数,用来修改闭包中使用的自由变量。
在Python3中使用nonlocal访问嵌套作用域中的变量引用
1 # coding:utf8 2 from functools import wraps 3 4 import time 5 import logging 6 7 8 def warn(timeout): 9 timeout = [timeout] 10 def decorator(func): 11 def wrapper(*args,**kargs): 12 start = time.time() 13 res = func(*args,**kargs) 14 used = time.time() - start 15 if used > timeout[0]: 16 msg = '"%s": %s > %s' % (func.__name__,used,timeout[0]) 17 logging.warn(msg) 18 return res 19 def setTimeout(k): 20 # Python3中有nonlocal来改变变量timeout的作用范围,Python2中使用可变列表来实现 21 # nonlocal timeout 22 # timeout = k 23 timeout[0] = k 24 wrapper.setTimeout = setTimeout 25 26 return wrapper 27 return decorator 28 29 from random import randint 30 @warn(1.5) 31 def test(): 32 print('in test') 33 while randint(0,1): 34 time.sleep(0.5) 35 36 for _ in range(30): 37 test() 38 39 test.setTimeout(1) 40 41 for _ in range(30): 42 test()