案例:
实现一个能将函数调用信息记录到日志的装饰器
需求:
把每次函数的调用时间,执行时间,调用次数写入日志
可以对被装饰函数分组,调用信息记录到不同日志
动态修改参数,比如日志格式
动态打开关闭日志输出功能
如何解决这个问题?
为了装饰器的灵活性,定义一个装饰类,把这个类的实例方法当做装饰器,在类中装饰器方法持有实例对象,便于修改属性和扩展功能
#!/usr/bin/python3
import logging
from time import time, strftime, localtime, sleep
from random import choice
from functools import wraps
class 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_log
def func_one():
print(‘one‘)
@log_one.go_log
def func_two():
print(‘two‘)
@log_two.go_log
def 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]))
原文地址:http://www.cnblogs.com/2bjiujiu/p/7294445.html