python_如何在类中定义装饰器,,案例: 实现一个能将


案例:

实现一个能将函数调用信息记录到日志的装饰器

需求:

把每次函数的调用时间,执行时间,调用次数写入日志可以对被装饰函数分组,调用信息记录到不同日志动态修改参数,比如日志格式动态打开关闭日志输出功能

如何解决这个问题?

  为了装饰器的灵活性,定义一个装饰类,把这个类的实例方法当做装饰器,在类中装饰器方法持有实例对象,便于修改属性和扩展功能

#!/usr/bin/python3import loggingfrom time import time, strftime, localtime, sleepfrom random import choicefrom functools import wrapsclass ToLog():    def __init__(self, name):        log = logging.getLogger(name)        log.setLevel(logging.INFO)        # 日志保存文件名字        file_name = logging.FileHandler(name + ‘.log‘)        # 添加日志文件        log.addHandler(file_name)        # 日志格式        log.info(‘start‘.center(50, ‘-‘))        self.log = log        self.temp = ‘%(func)s -> [%(start_time)s - %(used_time)s - %(naclls)s]‘        def go_log(self, func):        @wraps(func)        def wrapper(*args, **kwargs):            # 函数每调用一次加1            wrapper.naclls += 1                        start_time = time()            res = func(*args, **kwargs)            used_time = time() - start_time                        info = {}            info[‘func‘] = func.__name__            info[‘start_time‘] = start_time            info[‘used_time‘] = used_time            info[‘naclls‘] = wrapper.naclls                        msg = self.temp % info            # 把日志按格式写入文件            self.log.info(msg)                        return res                # 初始化调用次数参数        wrapper.naclls = 0                return wrapper        # 重新定义日志记录模版    def set_log_temp(self, temp):        self.temp = temp    # 关闭日志功能    def log_off(self):        self.log.setLevel(logging.WARN)        # 打开日志功能    def log_on(self):        self.log.setLevel(logging.INFO)# 实例化出两个装饰器对象log_one = ToLog(‘one‘)log_two = ToLog(‘two‘)# 修改实例2的日志模版,去掉执行时间log_two.set_log_temp(‘%(func)s -> [%(start_time)s - %(naclls)s]‘)# 关闭log_two中记录日志功能log_two.log_off()@log_one.go_logdef func_one():    print(‘one‘)     @log_one.go_logdef func_two():    print(‘two‘)@log_two.go_logdef func_three():    print(‘three‘)if __name__ == ‘__main__‘:    for _ in range(50):        choice([func_one, func_two, func_three])()        sleep(choice([0.5, 1, 1.5]))

  

python_如何在类中定义装饰器

评论关闭