import functools
import time, math
import random
import types
class LoopTimeout():
‘‘‘
循环执行函数fn,直到超时退出
‘‘‘
timeout = 60 #超时时间
time_sleep_gap = 1 #每次间隔时间
def __init__(self, fn):
self.__fn = fn # 初始化操作在此完成
functools.wraps(self.__fn)(self)
def __call__(self, *args, **kwargs): # 实现__call__方法,表示对象是一个可调用对象,可以像调用函数一样进行调用
start_time = time.time()
while time.time() - start_time < self.timeout:
bool_ret = self.__fn(*args, **kwargs)
if bool_ret:
cost_time = time.time() - start_time
print("function: {} check true, cost time: {:.4f}".format(self.__fn.__name__, cost_time))
return True, cost_time
time.sleep(self.time_sleep_gap)
else:
cost_time = time.time() - start_time
print("time out, function: {} check false, cost time: {:.4f}".format(self.__fn.__name__, cost_time))
return False, cost_time
def __get__(self, instance, cls):
‘‘‘
修饰成员函数
‘‘‘
if instance is None:
return self
else:
return types.MethodType(self, instance)
@staticmethod
def set(timeout, time_sleep_gap):
LoopTimeout.timeout = timeout
LoopTimeout.time_sleep_gap = time_sleep_gap
def execute_time(func):
# 定义装饰器
# 此时调用f()时,实际上调用的是wrapper函数,返回值一样,但名字变了。
@functools.wraps(func) # 把名字改回来
def wrapper(*args, **kw):
start_time = time.time()
res = func(*args, **kw)
end_time = time.time()
cost_time = end_time-start_time
print("function {}, excute time is {:.4f}".format(func.__name__, cost_time) )
return res, cost_time
return wrapper
def loop_count(loop_num=1, loop_descrip=("result", "time")):
"""
循环并统计函数fn的执行结果
"""
def parse_count(dict_list):
assert isinstance(dict_list, dict)
for key, value in dict_list.items():
if not value:
continue
if isinstance(value[0], bool):
succ_sum = 0
for v in value:
succ_sum = succ_sum+1 if v else succ_sum
succ_rate = succ_sum*1.0/len(value)
count_desc = f"{key}-> succucc rate: {succ_rate:.4f}"
elif isinstance(value[0], int) or isinstance(value[0], float):
max_v, min_v, avg_v = max(value), min(value), sum(value)*1.0/len(value)
count_desc = f"{key}-> max:{max_v:.4f}, min:{min_v:.4f}, avg:{avg_v:.4f}"
print(count_desc)
def loop_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
res_dict_list = {}
for desc in loop_descrip:
res_dict_list[desc] = []
for i in range(loop_num):
res = func(*args, **kw)
res_tuple = (res, ) if isinstance(res, str) or isinstance(res, int) or isinstance(res, float) else res
for desc, res in dict(zip(loop_descrip, res_tuple)).items():
res_dict_list[desc].append(res)
if (i!=0 and i % 10 == 0) or i == loop_num-1:
print("loop numbers: {}".format(i+1))
parse_count(res_dict_list)
return wrapper
return loop_decorator
@execute_time
def test_excute_time():
time.sleep(random.randint(1,5))
print("test ....")
@loop_count(10, ("ret","cost_time"))
def test_loop_count():
a = random.randint(0,1)
t = random.random()
return (a==0, t)
@LoopTimeout
def test_loop_timeout():
return random.randint(0, 5) > 5
@execute_time
def test_case():
print("*"*30)
test_excute_time()
print("*"*30)
test_loop_count()
print("*"*30)
LoopTimeout.set(10, 1)
test_loop_timeout()
print("*"*30)
if __name__ == "__main__":
test_case()
test ....
function test_excute_time, excute time is 5.0265
******************************
loop numbers: 10
ret-> succucc rate: 0.6000
cost_time-> max:0.8693, min:0.0288, avg:0.4082
******************************
time out, function: test_loop_timeout check false, cost time: 10.0565
function test_case, excute time is 15.0873
原文:https://www.cnblogs.com/rsrm/p/14721573.html