在某项目中,程序运行效率较差,为分析程序内哪些函数执行时间开销较大,我们实现了一个带timeout参数的函数装饰器。装饰功能如下:
@warn_timeout(1.5)def func(a,b): ...
要求:
统计被装饰函数单次调用运行时间;
时间大于参数timeout的,将此次函数调用记录到log日志中;
运行时可修稿timeout的值。
解决方案:
为包裹函数增加一个函数,用来修改闭包中使用的自由变量。在Python3中,使用 nonlocal 关键词访问嵌套作用域中的变量引用。
对于 nonlocal 关键字:nonlocal 表示将变量声明为外层变量(外层函数的局部变量,而且不能是全局变量)。
global 表示将变量声明为全局变量。两个关键词都用于允许在一个局部作用域中使用外层的变量。
方案示例:import time, logging, randomdef warn_timeout(timeout):
def decorator(func):
def wrap(*args, **kwargs):
t0 = time.time()
res = func(*args, **kwargs)
used = time.time() - t0 if used > timeout:
logging.warning('%s: %s > %s' % (func.__name__, used, timeout))
return res def set_timeout(new_timeout):
nonlocal timeout
timeout = new_timeout
wrap.set_timeout = set_timeout return wrap return decorator
@warn_timeout(1)def f(i):
print('in f [%s]' % i)
while random.randint(0, 1):
time.sleep(0.6)for i in range(10):
f(i)f.set_timeout(1.5)for i in range(10):
f(i)结果:
in f [0] in f [1] in f [2] in f [3] in f [4] WARNING:root:f: 2.40358567237854 > 1 in f [5] in f [6] WARNING:root:f: 1.2016241550445557 > 1 in f [7] WARNING:root:f: 1.8050942420959473 > 1 in f [8] in f [9] WARNING:root:f: 1.8009305000305176 > 1 in f [0] in f [1] in f [2] in f [3] in f [4] in f [5] in f [6] WARNING:root:f: 1.802403211593628 > 1.5 in f [7] in f [8] in f [9]
查看更多关于47. 实现属性可修改的函数装饰器的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did126753