#利用装饰接受参数,来统计函数执行是否超过了设置的秒数,并可以随时修改装饰器的参数
import time
import logging
def 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 # nonlocal改变 变量的引用的值,只能在python3用
#nonlocal关键字用来在函数或其他作用域中使用外层(非全局)变量
timeout = new_timeout # 把新值传给timeout
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): # 这里也非常优秀相当于 50%的几率
time.sleep(0.6)
for i in range(20):
f(i)
f.set_timeout(1) # 函数的变量相当于调了函数,改变了参数的值
for i in range(20):
f(i)
#在python2中没有nonlocal这个,可以利用列表是可变属性,来实行更改值
import time
import logging
def warn_timeout(timeout):
def decorator(func):
_timeout = [timeout] #在这先弄一个列表
def wrap(*args, **kwargs):
timeout = _timeout[0] #每次调取的列表的第0个值,
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
_timeout[0] = new_timeout #改变的话,就改变列表的第0个值
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)