如何让自定义json.JSONEncoder对符合条件的字符串执行截断处理?
问题原因
json.JSONEncoder的default方法仅会在遇到JSON无法原生序列化的非标准类型(比如datetime)时被调用。字符串属于Python原生可序列化类型,编码器会直接处理,根本不会进入default方法,所以你的截断逻辑对长字符串无效。
解决方案
要处理字符串类型,需要重写编码器的_iterencode方法——这个方法是编码器内部逐个处理所有待序列化元素的核心逻辑,所有类型的元素都会经过它的处理。以下是修改后的代码:
import json from datetime import datetime from json.encoder import encode_basestring_ascii class StringShortener(json.JSONEncoder): def default(self, obj): # 保留原有的datetime处理逻辑 if isinstance(obj, datetime): return obj.isoformat() return super().default(obj) def _iterencode(self, obj, markers=None): # 拦截字符串类型,判断长度后截断 if isinstance(obj, str): if len(obj) > 10: truncated_str = obj[:10] + '...' # 调用编码器原生的字符串编码方法处理截断后的内容 yield encode_basestring_ascii(truncated_str) return # 调用父类逻辑处理其他所有类型 yield from super()._iterencode(obj, markers) # 测试示例 data = { "dummy": "a very long string that should be truncated", "date": datetime.now() } print(json.dumps(data, cls=StringShortener))
补充说明
- 如果需要支持Unicode字符串的完整编码,可以将
encode_basestring_ascii替换为encode_basestring。 - 原有的
default方法逻辑可以保留,继续处理datetime这类非原生序列化类型。
内容的提问来源于stack exchange,提问作者MortenB
相关产品推荐
相关产品推荐

