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

使用Loguru时如何自行处理自定义字符引发的UnicodeEncodeError?

解决Loguru中自定义字符引发的UnicodeEncodeError问题

针对Loguru处理含自定义/非法Unicode字符时抛出的UnicodeEncodeError,可以通过以下几种方式自行处理:

1. 直接指定编码错误处理策略

Loguru的add()方法支持encoding_errors参数,可直接设置系统内置的错误处理规则,比如replace、ignore、backslashreplace等,快速解决编码问题:

from loguru import logger
import sys

# 移除默认处理器,添加新处理器并指定编码错误策略
logger.remove()
logger.add(sys.stdout, encoding_errors="replace")

# 测试含非法Unicode字符的日志
logger.info("包含自定义字符:\uD800\uDCFF")

如果需要自定义错误逻辑,还可以传入一个错误处理函数:

def custom_encode_error_handler(exception):
    # exception为UnicodeEncodeError实例,返回(替换字节, 继续处理的位置)
    return (b"[无法编码字符]", exception.start + 1)

logger.remove()
logger.add(sys.stdout, encoding_errors=custom_encode_error_handler)

2. 自定义安全输出流

创建一个包装类,重写write方法捕获编码错误,按需处理后再输出到原流,适合需要完全控制输出逻辑的场景:

import sys
from loguru import logger

class SafeOutputStream:
    def __init__(self, stream):
        self.stream = stream
        self.default_encoding = stream.encoding or "utf-8"

    def write(self, message):
        try:
            self.stream.write(message)
        except UnicodeEncodeError:
            # 将无法编码的字符替换为?后再输出
            safe_msg = message.encode(self.default_encoding, errors="replace").decode(self.default_encoding)
            self.stream.write(safe_msg)
        self.stream.flush()

    def flush(self):
        self.stream.flush()

# 替换默认输出流为自定义安全流
logger.remove()
logger.add(SafeOutputStream(sys.stdout))

# 测试
logger.info("包含自定义字符:\uD800\uDCFF")

3. 日志消息前置过滤

通过Loguru的filter机制,在日志输出前提前检测并处理无法编码的字符,避免后续抛出错误:

from loguru import logger
import sys

def safe_message_filter(record):
    target_encoding = record["extra"].get("log_encoding", "utf-8")
    try:
        # 尝试编码,检测是否有问题
        record["message"].encode(target_encoding)
    except UnicodeEncodeError:
        # 替换无法编码的字符
        record["message"] = record["message"].encode(target_encoding, errors="replace").decode(target_encoding)
    return True

logger.remove()
logger.add(sys.stdout, filter=safe_message_filter)

# 测试
logger.info("包含自定义字符:\uD800\uDCFF")

根据实际需求选择方案:简单场景用encoding_errors参数即可;复杂逻辑优先考虑自定义流或过滤器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 04:50:25