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

如何在Python 3中高效记录字节字符串日志?

Python3日志输出字节串的解决方案

Python3内置logging的核心限制

Python3的logging模块默认会将所有日志参数转换为字符串类型。当传入bytes对象时,会直接调用str(bytes),导致输出带b''标识的内容,无法像Python2那样直接输出原始字节内容。


解决方案

1. 自定义日志处理器与格式化器(推荐)

通过继承logging的处理器和格式化器,实现对bytes对象的直接输出,既保留Python3日志系统的原有功能,又兼容Python2的字节串输出逻辑。

代码示例:

import logging
from logging import StreamHandler, Formatter

class BytesFormatter(Formatter):
    def format(self, record):
        # 针对bytes类型消息直接格式化,不转换为str
        if isinstance(record.msg, bytes):
            return record.msg % record.args
        # 非bytes消息按原有逻辑处理
        return super().format(record)

class BytesStreamHandler(StreamHandler):
    def emit(self, record):
        try:
            msg = self.format(record)
            if isinstance(msg, bytes):
                # 直接写入字节串,追加换行符的字节形式
                self.stream.write(msg)
                self.stream.write(self.terminator.encode('utf-8'))
            else:
                # 字符串消息按原有逻辑写入
                self.stream.write(msg + self.terminator)
            self.flush()
        except RecursionError:
            raise
        except Exception:
            self.handleError(record)

# 业务代码部分
tar_inc_page = 1024
elem = lambda: None
elem.name = b'_demo_vec'
elem.base = 0x2000003c
elem.size = 4

# 日志配置
LOG = logging.getLogger(__name__)
LOG.setLevel(logging.INFO)

# 移除默认处理器,避免重复输出
for handler in LOG.root.handlers[:]:
    LOG.root.removeHandler(handler)

# 添加自定义处理器和格式化器
handler = BytesStreamHandler()
handler.setFormatter(BytesFormatter())
LOG.addHandler(handler)

# 输出日志
LOG.info(b"using tar inc page size of %d" % tar_inc_page)
LOG.info(b"%8s = 0x%08x + 0x%04x" % (elem.name, elem.base, elem.size))

运行后输出与Python2一致:

INFO:main:using tar inc page size of 1024
INFO:main:_demo_vec = 0x2000003c + 0x0004

2. 显式解码字节串为字符串(最简单)

如果你的字节串均为UTF-8编码,直接在日志调用时将bytes解码为str即可,无需修改日志系统:

import logging
logging.basicConfig(level=logging.INFO)
LOG = logging.getLogger(__name__)

# 业务代码同前...

LOG.info((b"using tar inc page size of %d" % tar_inc_page).decode('utf-8'))
LOG.info((b"%8s = 0x%08x + 0x%04x" % (elem.name, elem.base, elem.size)).decode('utf-8'))

3. 使用跨版本兼容的第三方日志库

若需要全面兼容Python2和Python3,可使用loguru库——它原生支持Python2.7及Python3.5+,且能通过配置实现类似Python2的字节串输出效果。

安装命令:

pip install loguru

使用示例:

from loguru import logger

# 业务代码同前...

# 配置日志直接输出原始内容
logger.add(lambda msg: print(msg, end=''), format="{message}")
logger.info(b"using tar inc page size of %d" % tar_inc_page)
logger.info(b"%8s = 0x%08x + 0x%04x" % (elem.name, elem.base, elem.size))

总结

  • Python3内置logging默认不支持直接输出字节串,但可通过自定义处理器和格式化器实现。
  • 最简便的方式是显式将UTF-8编码的字节串解码为字符串。
  • 跨版本兼容场景可选择loguru这类第三方库。

内容的提问来源于stack exchange,提问作者personal_cloud

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 20:05:16