如何实现属性可修改的函数装饰器?

需求:
在某项目中,程序运行效率较差,为分析程序内哪些函数的执行开销较大,我们实现了一个 带timeout参数的函数装饰器,装饰功能如下:
@warn_timeout(1.5)
def func(a,b):
...
1、统计被装饰函数的单次调用运行时间
2.时间大于参数timeout的,将此次函数调用记录到log日志中
3、运行时可修改timeout的值

思路:
1、为包裹函数添加一个函数,用来修改闭包中使用的自由变量
2、在python3中:使用nonlocal访问嵌套作用域中的变量引用

代码:

#coding:utf-8
import time
import logging

def warn_timeout(timeout):
    def decorator(func):
        _timeout = [timeout] # python2中的实现
        def wrap(*args,**kwargs):
            timeout = _timeout[0] # python2中的实现
            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 # python3中的实现
            _timeout[0]  = new_timeout # python2中的实现
        wrap.set_timeout = set_timeout
        return wrap
    return decorator


import random
@warn_timeout(1.5)
def f(i):
    print('in f [%s]' % i)
    while random.randint(0,1):
        time.sleep(0.6)
    

for i in range(30):
    f(i)

f.set_timeout(1)
for i in range(30):
    f(i)

原文地址:https://www.cnblogs.com/Richardo-M-Q/p/13959093.html