翼度科技»论坛 编程开发 python 查看内容

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

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
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 参数不要重复,特别是在类的构造函数中。

来源:https://www.cnblogs.com/yuzhihui/p/18568131
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具