使用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
相关产品推荐
相关产品推荐

