Pythonic方式实现返回自定义日志对象,替代劫持__new__的不规范用法
问题核心根源
你当前的实现本质是把CustomLogger类伪装成了一个无参数的工厂函数,通过劫持__new__方法绕过了Python类的实例化流程:
__new__的设计作用是创建并返回当前CustomLogger类的实例,只有返回值是CustomLogger实例时,才会自动调用__init__方法完成属性初始化- 你直接返回了外部的
logging.Logger实例,自然无法通过__init__扩展参数,也不符合Python面向对象的设计规范 - 额外还有隐藏问题:每次调用
CustomLogger()都会重复给root logger添加handler,会导致同一条日志多次输出的bug
正确实现思路及逻辑
1. 用工厂函数替代伪装类
你的需求本质是生成预配置的Logger实例,属于典型的工厂模式场景,完全不需要套类外壳,直接定义独立的工厂函数即可:
- 所有原本写在
__new__里的配置逻辑都可以直接迁移到函数中 - 要扩展参数直接在函数定义时添加即可,比如支持传入日志级别、是否添加文件handler、自定义日志级别列表等,没有任何限制
- 可以内置重复配置检测,避免重复添加handler、重复注册日志级别
2. 拆分通用工具逻辑
原本类中的addLoggingLevel、CustomFormatter都是通用的无状态工具,可以独立拆分:
addLoggingLevel可以定义为独立函数,也可以加@staticmethod装饰后放到工具类中CustomFormatter作为独立的Formatter子类存在,和工厂逻辑解耦,方便后续单独修改格式规则
3. 优化调用逻辑
你现有的模块级日志判断逻辑可以直接封装到工厂函数中,外部调用无需重复写if __name__ == "__main__"的判断,减少冗余代码。
极简示例参考
import logging from datetime import datetime # 独立的自定义日志级别注册函数 def addLoggingLevel(levelName:str, levelNumber:int, methodName:str=None, exitAfter:bool=False,force:bool=False): # 你原有的实现不变,此处省略完整代码 pass # 独立的自定义格式化类 class CustomFormatter(logging.Formatter): # 你原有的实现不变,此处省略完整代码 pass # 日志工厂函数,支持自定义参数扩展 def get_custom_logger(name: str = None, default_level: int = logging.WARNING, add_console_handler: bool = True): # 注册自定义日志级别,全局只执行一次 if not hasattr(logging, 'TRACE'): addLoggingLevel(levelName='VERBOSE',levelNumber=15) addLoggingLevel(levelName='FATAL',levelNumber=15,exitAfter=True,force=True) addLoggingLevel(levelName='TRACE',levelNumber=9) logger = logging.getLogger(name) logger.setLevel(default_level) # 只给root logger添加控制台handler,避免重复添加导致日志重复输出 if add_console_handler and name is None and not any(isinstance(h, logging.StreamHandler) for h in logger.handlers): consoleHandler = logging.StreamHandler() consoleHandler.setFormatter(CustomFormatter()) logger.addHandler(consoleHandler) return logger
调用方式更简洁:
class Example(): def __init__(self): # 主进程传name=None获取配置好的root logger,其他模块传__name__获取对应模块的logger nlog = get_custom_logger(name=__name__ if __name__ != "__main__" else None) nlog.setLevel(20)
内容的提问来源于stack exchange,提问作者Nick W.
相关产品推荐
相关产品推荐

