ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

47. 实现属性可修改的函数装饰器

2021-04-25 09:57:12  阅读:156  来源: 互联网

标签:函数 47 WARNING timeout time root 装饰 def 属性


在某项目中,程序运行效率较差,为分析程序内哪些函数执行时间开销较大,我们实现了一个带timeout参数的函数装饰器。装饰功能如下:

@warn_timeout(1.5)def func(a,b):
    ...

要求:

  1. 统计被装饰函数单次调用运行时间;

  2. 时间大于参数timeout的,将此次函数调用记录到log日志中;

  3. 运行时可修稿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,WARNING,timeout,time,root,装饰,def,属性
来源: https://blog.51cto.com/u_10272167/2730221

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有