在我们使用log模块输出日志时,经常会遇到log输出重复的问题,如下:
先来看这个文件log.py的代码:
代码示例: ''' 功能描述:实现控制台和文件同时记录日志的功能 编写人:超哥 编写日期: 步骤分析: 1-配置日志记录器名称 2-配置日志级别 3-配置日志格式(可以分别设置,也可以统一设置) 4-创建并添加handler-控制台 5-创建并添加handler-文件 6-提供对外获取logger ''' import logging import sys def log(): # 1 - 配置日志记录器名称 logger = logging.getLogger('AutoTest') # 2-配置日志级别 logger.setLevel(logging.DEBUG) # 3-配置日志格式(可以分别设置,也可以统一设置) format = logging.Formatter('%(name)s-%(asctime)s-%(message)s') # 4 - 创建并添加handler - 控制台 sh = logging.StreamHandler() sh.setFormatter(format) logger.addHandler(sh) # 5 - 创建并添加handler - 文件 fh = logging.FileHandler('test.log') fh.setFormatter(format) logger.addHandler(fh) # 6 - 提供对外获取logger return logger if __name__ == '__main__': logger = log() logger.info('使用函数定义的log方法')
我们在同一目录下创建另外一个文件:
在我们导入写好的log.py文件
from xx目录 import log log().info('xxx1') log().info('xxx2') log().info('xxx3')
输出:
这个结果什么鬼?明明三句话,打印出来这么多,这其实是log在使用的常遇到的坑,通过debug你会发现,每次调用都会创建句柄,所以重复,如图:
第一句调用之后,handlers里面已经存在了两个handler,分别是控制台句柄StreamHandler和文件句柄FileHandler,下面图中是第二句调用添加句柄
执行后会发现handlers里面多了一个StreamHandler
怎么解决这种情况,有两个方案,咱们分别列出两种方案代码:
第一种,第一使用单例模式,在log.py文件中增加一行:logger = log() ,这句的作用就是提前实例化好对象,其他模块使用都适用该对象,所以别的模块导入语句要改成:from xxx包.log import logger ,然后使用logger.info('xxxx') 输出日志即可
……省略上方代码
# 6 - 提供对外获取logg的方法 return logger #增加一行 logger = log() if __name__ == '__main__': logger = log() logger.info('使用函数定义的log方法')
导入:
from xx包 import logger logger.info('xxx1') logger.info('xxx2') logger.info('xxx3')
输出:
第二个方案:log.py每次判断handlers是否已存在
…… # 4 - 创建并添加handler - 控制台 sh = logging.StreamHandler() sh.setFormatter(format) # 5 - 创建并添加handler - 文件 fh = logging.FileHandler('test.log') fh.setFormatter(format) #在新增handler时判断是否为空 if not logger.handlers: logger.addHandler(sh) logger.addHandler(fh) # 6 - 提供对外获取logg的方法 return logger if __name__ == '__main__': logger = log() logger.info('使用函数定义的log方法')
导入文件代码保持不变:
from xx包 import log log().info('xxx1') log().info('xxx2') log().info('xxx3')
输出:
针对面向对象的方案同样是以上两个,请自行解决
总结
到此这篇关于python控制台打印log输出重复解决的文章就介绍到这了,更多相关python打印log重复内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!