本篇文章小编给大家分享一下python控制台打印log输出重复解决方法,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。
在我们使用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')
输出:
针对面向对象的方案同样是以上两个,请自行解决