​ 在学习了python的函数式编程后,又接触到了logging这样一个强大的日志模块。为了减少重复代码,应该不少同学和我一样便迫不及待的写了一个自己的日志函数,比如下面这样:

# 这里为了便于理解,简单的展示了一个输出到屏幕的日志函数

def my_log():

logger= logging.getLogger('mysql.log')

ch=logging.StreamHandler()

ch.setLevel(logging.ERROR)

fmt= logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setFormatter(fmt)

logger.addHandler(ch)returnlogger

my_log().error('run one')

my_log().error('run two')

my_log().error('run three')

函数写好了,看起来似乎也没有问题,我们来运行一下!

结果如下:

2018-06-21 13:06:37,569 - mysql.log - ERROR -run one2018-06-21 13:06:37,569 - mysql.log - ERROR -run two2018-06-21 13:06:37,569 - mysql.log - ERROR -run two2018-06-21 13:06:37,569 - mysql.log - ERROR -run three2018-06-21 13:06:37,569 - mysql.log - ERROR -run three2018-06-21 13:06:37,569 - mysql.log - ERROR - run three

日志居然重复输出了,且数量递增。

问题解析

实际上logger = logging.getLogger('mysql.log')在执行时,没有每次生成一个新的logger,而是先检查内存中是否存在一个叫做‘mysql.log’的logger对象,存在则取出,不存在则新建。

实例化的logger对象具有‘handlers’这样一个属性来存储 Handler,代码演示如下:

def my_log():

logger= logging.getLogger('mysql.log')

# 每次被调用后打印出logger的handlers列表

print(logger.handlers)

ch=logging.StreamHandler()

ch.setLevel(logging.ERROR)

fmt= logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setFormatter(fmt)

logger.addHandler(ch)returnlogger

my_log().error('run one')

my_log().error('run two')

my_log().error('run three')

运行结果:

[]2018-06-21 13:26:14,059 - mysql.log - ERROR -run one

[ (ERROR)>]2018-06-21 13:26:14,060 - mysql.log - ERROR -run two2018-06-21 13:26:14,060 - mysql.log - ERROR -run two

[ (ERROR)>, (ERROR)>]2018-06-21 13:26:14,060 - mysql.log - ERROR -run three2018-06-21 13:26:14,060 - mysql.log - ERROR -run three2018-06-21 13:26:14,060 - mysql.log - ERROR - run three

logger.handlers最初是一个空列表,执行‘logger.addHandler(ch)’添加个‘StreamHandler’,输出一条日志

在第二次被调用时,logger.handlers已经存在一个‘StreamHandler’,再次执行‘logger.addHandler(ch)’就会再次添加一个‘StreamHandler’,此时的logger有两个个‘StreamHandler’,输出两条重复的日志

在第三次被调用时,logger.handlers已经存在两个‘StreamHandler’,再次执行‘logger.addHandler(ch)’就会再次添加一个,此时的logger有三个‘StreamHandler’,输出三条重复的日志

解决办法

1.改名换性

# 为日志函数添加一个name,每次调用时传入不同的日志名

def my_log(name):

logger=logging.getLogger(name)

ch=logging.StreamHandler()

ch.setLevel(logging.ERROR)

fmt= logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setFormatter(fmt)

logger.addHandler(ch)returnlogger

my_log('log1').error('run one')

my_log('log2').error('run two')

my_log('log3').error('run three')

运行结果:

2018-06-21 13:40:51,685 - log1 - ERROR -run one2018-06-21 13:40:51,685 - log2 - ERROR -run two2018-06-21 13:40:51,685 - log3 - ERROR - run three

2.及时清理(logger.handlers.clear)

def my_log():

logger=logging.getLogger(name)

# 每次被调用后,清空已经存在handler

logger.handlers.clear()

ch=logging.StreamHandler()

ch.setLevel(logging.ERROR)

fmt= logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setFormatter(fmt)

logger.addHandler(ch)returnlogger

my_log().error('run one')

my_log().error('run two')

my_log().error('run three')

ps:removeHandler方法(兼容性较差)

# 这种写法下的可以使用removeHandler方法(logger.handlers.clear也可以使用在这种写法的函数内)

import logging

def my_log(msg):

logger= logging.getLogger('mysql.log')

ch=logging.StreamHandler()

ch.setLevel(logging.ERROR)

fmt= logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setFormatter(fmt)

logger.addHandler(ch)

logger.error(msg)

# 在使用完ch后从移除

logger.removeHandler(ch)

my_log('run one')

my_log('run two')

my_log('run three')

3.用前判断

import logging

def my_log():

logger= logging.getLogger('mysql.log')

# 判断logger是否已经添加过handler,是则直接返回logger对象,否则执行handler设定以及addHandler(ch)ifnot logger.handlers:

ch=logging.StreamHandler()

ch.setLevel(logging.ERROR)

fmt= logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setFormatter(fmt)

logger.addHandler(ch)returnlogger

my_log().error('run one')

my_log().error('run two')

my_log().error('run three')

python重复输出_python日志重复输出相关推荐

  1. python log模块_python日志模块logbook使用方法

    python自带了日志模块logging,可以用来记录程序运行过程中的日志信息.同时python还有logbook模块用来取代logging模块,在很多的项目中logbook模块使用也是比较的多,因此 ...

  2. linux 输出gc日志,Tomcat输出保存JVM GC日志文件

    当系统出现问题时,分析java虚拟机GC日志可以帮助我们定位问题,一般来说, 我们可以通过制定JVM参数使tomcat保存GC日志文件,具体实现如下: Windows下 找到tomcat的解压目录,进 ...

  3. python123格式化输出_python 字符串格式化输出 %d,%s及 format函数

    旧式格式化方式:%s,%d 1.顺序填入格式化内容 s = "hello %s, hello %d"%("world", 100) print(s) 结果: ' ...

  4. python stdout stderr 一起输出_Python日志记录在stdout和stderr之间拆分

    Is it possible to have python logging messages which are INFO or DEBUG to go to stdout and WARNING o ...

  5. python列表添加重复值_python 列表 重复添加数据库

    <Python 3程序开发指南(第2版•修订版)>--1.4 总结 本节书摘来自异步社区<Python 3程序开发指南(第2版•修订版)>一书中的第1章,第1.4节,作者[英] ...

  6. python去重复记录_python如何处理重复值数据?

    一起学习,一起成长! 前言 在实际数据采集.数据处理和数据分析中,经常会遇到的一个问题就是:重复数据.重复数据在进行数据分析或数据挖掘的过程中,对其输出结果有重要的影响.比如,在逻辑回归分析中,重复数 ...

  7. python字典倒序_python字典倒序输出-女性时尚流行美容健康娱乐mv-ida网

    女性时尚流行美容健康娱乐mv-ida网 mvida时尚娱乐网 首页 美容 护肤 化妆技巧 发型 服饰 健康 情感 美体 美食 娱乐 明星八卦 首页 > 高级搜索 python 字典 内置方法ge ...

  8. python语言格式化输出_Python format()格式化输出方法详解

    原标题:Python format()格式化输出方法详解 format() 方法的语法格式如下: str.format(args) 此方法中,str 用于指定字符串的显示样式:args 用于指定要进行 ...

  9. python右对齐格式化输出_Python中格式化输出的两种方法介绍

    本篇文章给大家带来的内容是关于Python中格式化输出的两种方法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 方式一:使用占位符 % 常用占位符:% s (s = string ...

  10. python语言格式化输出_Python字符串格式化输出

    原博文 2019-11-22 12:48 − 本文链接:https://www.cnblogs.com/zyuanlbj/p/11910913.html 使用占位符%s name = '小飞' pri ...

最新文章

  1. Postgresql的使用
  2. 5GS 协议栈 — PFCP 协议 — BAR 缓存行为规则
  3. python数据可视化库 动态的_Python数据可视化:Pandas库,只要一行代码就能实现...
  4. 自己写一个树形导航菜单
  5. 企业服务总线需求说明
  6. Android之jni解决JNIEnv跨线程问题
  7. tcp http socket
  8. 信息学奥赛一本通(1151:素数个数)
  9. [数据结构与算法]RED-BLACK(红黑)树的实现TreeMap源码阅读
  10. 关于VM14中安装win 10遇到的小问题
  11. Electron介绍(一)
  12. 网页版bpc电波对时_bpc电波对时app下载
  13. HTTP请求报文和响应报文、http协议状态码分类和常用状态码、Cookie、curl工具、httpd自带的工具、压力测试工具
  14. 组会 | RELAXLOSS: DEFENDING MEMBERSHIP INFERENCE ATTACKS WITHOUT LOSING UTILITY
  15. 关系数据库——关系操作和关系完整性
  16. sendgrid_使用SendGrid处理传入的电子邮件
  17. 《游戏设计艺术(第2版)》——学习笔记(24)第24章 其他玩家有时会形成社群
  18. [8]Deep Learning Software-深度学习软件
  19. description标签如何正确使用?
  20. 解决Axure的元件库中部分原件不可使用的方法

热门文章

  1. linux信任公钥的配置
  2. Gprinter Android SDK V2.1 使用说明
  3. 连接 mysql 数据库失败频繁的原因探秘
  4. family album U.S.A 02
  5. wordpress如何获得当前用户的头像
  6. CodeBlocks中文乱码
  7. mysql导入存储过程报错_mysql导入存储过程时declare报错的有关问题解决
  8. pygame里面物体闪烁运动_关于“雷氏力学”运动力在空间上积累的一点研究(1)...
  9. java中example函数作用,MyBatis逆向工程中的Mapper接口以及Example的实例函数及详解...
  10. cls_template.php on line 1067,ecshop php5.5兼容utf-8版本