【笔记】如何实现属性可修改的函数装饰器

为分析程序内哪些函数执行时间开销较大,我们定义一个带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()

 

posted @ 2017-06-02 14:36  banshaohuan  阅读(294)  评论(0编辑  收藏  举报