Python 类的构造函数中初始化日志记录器后,导致日志被重复打印 ...

守听  金牌会员 | 2024-11-25 16:59:59 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 874|帖子 874|积分 2622

Python 类的构造函数中初始化日志记录器后,导致日志被重复打印

这个问题通常是由于添加处理器到同一个日志记录器上使用了全局的日志记录器,从而导致重复的日志记录。
以下是一些常见缘故原由以及解决方法:
问题缘故原由


  • 日志处理器未被精确检查或清算:
    每次实例化类时,假如给日志记录器添加了新的处理器而未清算旧处理器,会导致重复日志。
  • 使用了全局的日志记录器:
    直接使用 logging.getLogger() 而未设置局部的日志记录器,可能导致多个实例共享处理器。
示例问题代码
  1. import logging
  2. class MyClass:
  3.     def __init__(self):
  4.         self.logger = logging.getLogger("MyClass")
  5.         self.logger.info("Logger initialized")
  6. # 实例化多次
  7. a = MyClass()  # 打印一次日志
  8. b = MyClass()  # 打印两次日志
  9. c = MyClass()  # 打印三次日志
复制代码
解决方案

1. 检查并清算处理器

在类的构造函数中动态配置日志时,可以检查是否已经添加了处理器,避免重复添加。
改进后的代码:
  1. import logging
  2. class MyClass:
  3.     def __init__(self):
  4.         self.logger = logging.getLogger("MyClass")
  5.         if not self.logger.handlers:  # 只添加一次处理器
  6.             handler = logging.StreamHandler()
  7.             formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  8.             handler.setFormatter(formatter)
  9.             self.logger.addHandler(handler)
  10.         self.logger.info("Logger initialized")
  11. # 实例化多次
  12. a = MyClass()  # 打印一次日志
  13. b = MyClass()  # 无重复日志
  14. c = MyClass()  # 无重复日志
复制代码
2. 为每个类实例化独立的日志记录器

为每个类实例使用独立的日志记录器,并避免全局配置影响。
改进后的代码:
  1. import logging
  2. class MyClass:
  3.     def __init__(self):
  4.         self.logger = logging.getLogger(f"MyClass-{id(self)}")  # 使用唯一的日志名称
  5.         self.logger.setLevel(logging.INFO)
  6.         if not self.logger.handlers:  # 避免重复添加处理器
  7.             handler = logging.StreamHandler()
  8.             formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  9.             handler.setFormatter(formatter)
  10.             self.logger.addHandler(handler)
  11.         self.logger.info("Logger initialized")
  12. # 实例化多次
  13. a = MyClass()  # 每个实例独立的日志
  14. b = MyClass()
  15. c = MyClass()
复制代码
总结

要避免日志重复输出,关键是logging.getLogger()方法 name 参数不要重复,特殊是在类的构造函数中。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

守听

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表