Python logging.Formatter指定style为'{'仍采用%格式化报错求解
问题原因
你遇到的报错和Formatter设置的style参数完全无关,是混淆了logging体系中两个独立的格式化逻辑导致的:
- 日志消息与参数拼接阶段:调用
logger.warning(msg, *args)时,底层LogRecord.getMessage()方法默认硬编码使用%占位符语法拼接msg和传入的参数,和Formatter的配置没有任何关系。你传入的'info_msg {}'是str.format()的语法,用%拼接自然会触发参数不匹配的报错。 - 日志输出模板格式化阶段:Formatter的
style参数仅控制[{levelname}] {name}: {message}这类全局日志模板的格式化语法,只会作用于LogRecord的属性拼接,不会影响前面的消息和参数的拼接逻辑。
另外你提供的最小示例代码还存在一处遗漏:CustomLogger初始化了_console_handler,但没有调用self.addHandler(self._console_handler)把 handler 绑定到日志器上,实际运行时不会输出日志。
解决方案
根据你的使用需求可以二选一:
方案1:直接使用f-string拼接消息(成本最低)
调用日志方法时直接传入拼接完成的f-string,不需要传额外参数,完全避开默认的%拼接逻辑:
# main.py修改后 from logger import CustomLogger as CL logger = CL('test_logger') logger.warning(f'info_msg {1}')
方案2:重写LogRecord支持{}语法传参
如果你需要保持logger.warning('模板', 参数)的调用方式,且要用{}作为占位符,可通过自定义LogRecord替换默认的拼接逻辑:
修改后的logger.py代码:
# logger.py import logging from formatter import CustomFormatter class CustomLogRecord(logging.LogRecord): def getMessage(self): msg = str(self.msg) if self.args: # 替换为format语法拼接参数 msg = msg.format(*self.args) return msg class CustomLogger(logging.Logger): def __init__(self, name: 'str'): super().__init__(name) # 绑定自定义LogRecord生成逻辑 self.makeRecord = self._make_custom_record # 设置日志级别,按需调整 self.setLevel(logging.DEBUG) self._console_handler = logging.StreamHandler() format_string_for_console = '[{levelname}] {name}: {message}' time_format_string = '%Y-%m-%d %H:%M:%S%Z' console_formatter = CustomFormatter( fmt=format_string_for_console, datefmt=time_format_string, style='{' ) self._console_handler.setFormatter(console_formatter) # 把handler绑定到日志器 self.addHandler(self._console_handler) def _make_custom_record(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None): return CustomLogRecord(name, level, fn, lno, msg, args, exc_info, func, sinfo)
修改完成后运行原main.py代码即可正常输出日志,不需要调整调用方式。
内容的提问来源于stack exchange,提问作者Евгений Крамаров
相关产品推荐
相关产品推荐

