首页 > 编程语言 > 详细

python 装饰器

时间:2021-04-30 14:58:07      阅读:23      评论:0      收藏:0      [点我收藏+]
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

python 装饰器

原文:https://www.cnblogs.com/rsrm/p/14721573.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!