You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python logging.Formatter指定style为'{'仍采用%格式化报错求解

问题原因

你遇到的报错和Formatter设置的style参数完全无关,是混淆了logging体系中两个独立的格式化逻辑导致的:

  1. 日志消息与参数拼接阶段:调用logger.warning(msg, *args)时,底层LogRecord.getMessage()方法默认硬编码使用%占位符语法拼接msg和传入的参数,和Formatter的配置没有任何关系。你传入的'info_msg {}'是str.format()的语法,用%拼接自然会触发参数不匹配的报错。
  2. 日志输出模板格式化阶段: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,提问作者Евгений Крамаров

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 16:36:02