如何将Logger类实现为Singleton(单例)模式?
实现Logger单例的修改方案
核心修改思路
要将Logger类实现为单例,需确保整个程序中仅存在一个Logger实例,同时修复原代码中重复添加日志处理器导致的重复日志问题。
修改后的Logger类代码
import inspect import logging as log from env_setup import LOG_FILE # 明确导入,避免全局命名空间污染 class Logger: # 类变量存储唯一实例 _instance = None @classmethod def get_instance(cls): """获取Logger单例实例的类方法""" if not cls._instance: cls._instance = cls() return cls._instance def __init__(self): # 标记是否已完成初始化,避免重复执行__init__ if hasattr(self, '_initialized'): return self._initialized = True def custom_logger(self, level): logger_name = inspect.stack()[1][3] logger = log.getLogger(logger_name) logger.setLevel(level) # 检查是否已存在处理器,避免重复添加导致日志重复输出 if not logger.handlers: log_book = log.FileHandler(LOG_FILE) formatter = log.Formatter( "%(asctime)s - %(levelname)s - %(message)s", datefmt='%m/%d/%Y %I:%M:%S %p' ) log_book.setFormatter(formatter) logger.addHandler(log_book) return logger
修改后的调用代码
import logging as log class SomeClass: def __init__(self): # 获取Logger单例实例 self.logger = Logger.get_instance() self.log = self.logger.custom_logger(level=log.INFO) def some_func(self): try: 1 == 1 self.log.info('passed as correct') except Exception as e: self.log.error(f'errored: {str(e)}') raise Exception('Exception raised')
关键修改说明
- 单例实现:通过类方法
get_instance控制实例创建,确保全局仅存在一个Logger对象;__init__中添加_initialized标记,避免重复执行初始化逻辑。 - 日志处理器优化:添加
if not logger.handlers判断,防止每次调用custom_logger都新增文件处理器,导致同一条日志被多次写入文件。 - 代码规范优化:将
from env_setup import *改为明确导入LOG_FILE,减少全局命名空间冲突。
内容的提问来源于stack exchange,提问作者Micky
相关产品推荐
相关产品推荐

