必须用 json.dumps() 或 json.dump() 导出合法 JSON;嵌套结构需确保顶层为 dict/list,排除 set/datetime/自定义类等非标类型,避免循环引用和内存溢出。
用 json.dumps() 处理嵌套字典和列表,别直接 print
直接 print(data) 看起来像 json,其实只是 python 对象的字符串表示,缺引号、乱转义、不换行,根本不是合法 json。导出必须走 json.dumps() 或 json.dump()。
常见错误现象:TypeError: Object of type set is not JSON serializable —— 说明数据里混了 set、datetime、自定义类等非标准类型。
- 先检查数据结构:用
type(data)和isinstance(data, (dict, list))确认顶层是 dict/list - 遇到
set,提前转成list;遇到datetime,用isoformat()转字符串 - 简单兜底方案:传
default=str参数,但会把数字也变成字符串,慎用 - 示例:
json.dumps(data, indent=2, ensure_ascii=False)——indent控制缩进,ensure_ascii=False保留中文
关联数据有循环引用?用自定义 JSONEncoder
当 A 字段引用 B,B 又引用回 A(比如 ORM 模型间双向关系),json.dumps() 会报 RecursionError。这不是数据“太深”,而是存在引用环。
使用场景:Django Model 实例、SQLAlchemy 对象、手写的嵌套类实例。
- 不要手动删字段(容易漏或破坏结构),改用继承
json.JSONEncoder - 在
default方法里识别对象类型,只序列化需要的字段,跳过反向关系属性(如_state、user_set) - 避免在
default里调用vars(obj)或obj.__dict__,可能暴露出内部属性 - 示例:
json.dumps(obj, cls=CustomEncoder, indent=2),其中CustomEncoder重写了default
导出大文件时内存爆掉?改用 json.dump() 流式写入
json.dumps() 把整个结构转成一个大字符串再写入磁盘,100MB+ 的嵌套数据很容易触发 MemoryError。这时候必须绕过字符串中间态。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
性能影响:对 50MB 数据,dumps + write 可能占用 3 倍内存;dump 直接写文件,内存增量几乎恒定。
- 打开文件用
encoding='utf-8',否则 Windows 上可能写乱码 -
json.dump(data, f, indent=2, ensure_ascii=False)—— 注意参数顺序,f是文件对象,不是路径字符串 - 别用
open(path, 'w').write(json.dumps(...)),这是典型内存陷阱 - 如果数据是生成器(比如逐条查数据库),不能直接 dump,得先聚合为 list/dict,或改用
ijson库流式解析
Django/Flask 返回 JSON 时字段丢失?检查序列化前的数据净化
后端接口返回空对象、字段全 null、或抛 TypeError,大概率不是 JSON 模块问题,而是视图层拿出来的数据没清理干净。
常见错误现象:AttributeError: 'NoneType' object has no attribute 'id' 在序列化过程中出现 —— 说明关联字段是 None,但代码仍尝试取 .id。
- Django 中避免直接传
model_instance.__dict__,它包含_state等私有字段 - 用
model_to_dict()时加fields参数限定范围,或用serializers.serialize('json', [...])更安全 - Flask 中若用
jsonify(),确保传入的是纯 dict/list,不要传 model 实例或 query 结果集 - 关键点:JSON 序列化前的最后一层数据,必须是「可预测结构 + 无运行时依赖」,比如不能含 lambda、未求值的 QuerySet、带方法的实例










