J'Blog

11 课 · 日常

语义检索

基于 Chroma 向量库,与 Workspace 知识库分离。用自然语言描述你想查的内容。 非管理员每人每天可检索 5 次(消耗站点 AI 配额)。

JSON 序列化

原文:JSON 序列化

一句话

提供JSON编码和解码功能,实现Python对象与JSON格式之间的转换。

什么时候翻这页

  1. Agent需要解析来自外部API的JSON响应数据
  2. Agent需要将内部数据结构序列化为JSON格式以便存储或传输
  3. 在LangChain工具调用中处理结构化参数和返回值
  4. 需要自定义JSON编码/解码逻辑以支持特殊数据类型

核心概念

  1. JSON (JavaScript Object Notation):轻量级数据交换格式,基于JavaScript对象字面值语法
  2. 编码 (Encoding):将Python对象转换为JSON格式字符串的过程
  3. 解码 (Decoding):将JSON格式字符串转换为Python对象的过程
  4. 序列化 (Serialization):将Python对象转换为可存储或传输的格式(如JSON字符串)
  5. 反序列化 (Deserialization):从存储或传输的格式(如JSON字符串)重建Python对象
  6. 流式处理:使用dumpload函数处理文件流,适合大数据量场景

怎么做

  1. 基本编码:使用json.dumps()将Python对象转换为JSON字符串
import json
data = ['foo', {'bar': ('baz', None, 1.0, 2)}]
json_str = json.dumps(data)
# 输出: '["foo", {"bar": ["baz", null, 1.0, 2]}]'
  1. 基本解码:使用json.loads()将JSON字符串转换为Python对象
json_str = '["foo", {"bar":["baz", null, 1.0, 2]}]'
data = json.loads(json_str)
# 输出: ['foo', {'bar': ['baz', None, 1.0, 2]}]
  1. 文件流编码:使用json.dump()将Python对象直接写入文件
import json
from io import StringIO
io = StringIO()
json.dump(['streaming API'], io)
print(io.getvalue())
# 输出: '["streaming API"]'
  1. 文件流解码:使用json.load()从文件流读取JSON数据
import json
from io import StringIO
io = StringIO('["streaming API"]')
data = json.load(io)
# 输出: ['streaming API']
  1. 自定义编码:通过default参数处理非标准类型
import json
def custom_json(obj):
    if isinstance(obj, complex):
        return {'__complex__': True, 'real': obj.real, 'imag': obj.imag}
    raise TypeError(f'Cannot serialize object of {type(obj)}')

json.dumps(1 + 2j, default=custom_json)
# 输出: '{"__complex__": true, "real": 1.0, "imag": 2.0}'
  1. 自定义解码:使用object_hook参数转换特定JSON结构
import json
def as_complex(dct):
    if '__complex__' in dct:
        return complex(dct['real'], dct['imag'])
    return dct

json.loads('{"__complex__": true, "real": 1, "imag": 2}', object_hook=as_complex)
# 输出: (1+2j)
  1. 扩展JSONEncoder:通过继承JSONEncoder类添加自定义类型支持
import json
class ComplexEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, complex):
            return [obj.real, obj.imag]
        return super().default(obj)

json.dumps(2 + 1j, cls=ComplexEncoder)
# 输出: '[2.0, 1.0]'
  1. 格式化输出:使用indent参数美化JSON输出
import json
print(json.dumps({'6': 7, '4': 5}, sort_keys=True, indent=4))
# 输出:
# {
#     "4": 5,
#     "6": 7
# }
  1. 紧凑输出:使用separators参数生成最小化JSON
import json
json.dumps([1, 2, 3, {'4': 5, '6': 7}], separators=(',', ':'))
# 输出: '[1,2,3,{"4":5,"6":7}]'

命令 / API 速查

函数/方法描述示例
json.dumps(obj)将Python对象编码为JSON格式字符串json.dumps({'key': 'value'})
json.loads(s)将JSON格式字符串解码为Python对象json.loads('{"key": "value"}')
json.dump(obj, fp)将Python对象编码为JSON格式并写入文件流json.dump(data, open('file.json', 'w'))
json.load(fp)从文件流读取JSON数据并解码为Python对象json.load(open('file.json', 'r'))
JSONEncoder().encode(obj)将对象编码为JSON格式的字符串json.JSONEncoder().encode({'key': 'value'})
JSONEncoder().iterencode(obj)编码对象并生成字符串迭代器for chunk in json.JSONEncoder().iterencode(obj): ...

与 Agent 开发的联系

  1. 工具参数处理:在LangChain/LangGraph中,Agent调用工具时通常需要将参数序列化为JSON格式传递,并将返回的JSON响应解码为Python对象处理
  2. API响应解析:Agent调用外部API时,经常需要解析返回的JSON数据以提取有用信息,可以使用json.loads()json.load()进行解码
  3. 结构化输出:当需要Agent返回结构化数据时,可以使用json.dumps()将Python对象转换为JSON字符串,便于其他系统解析

初学者易错点

  1. 非字符串键:JSON中的键必须是字符串类型,Python字典中的非字符串键会被强制转换为字符串,可能导致loads(dumps(x)) != x
  2. 循环引用:默认情况下,JSON模块会检查循环引用,但可以通过check_circular=False禁用(可能导致无限递归)
  3. 非ASCII字符:默认情况下,ensure_ascii=True会转义非ASCII字符,如需保留原字符需设置为False
  4. NaN和无限值:JSON规范不支持NaN和无限值,但Python的JSON模块默认支持它们,可通过allow_nan=False禁用
  5. 重复键:JSON对象中的重复键会被接受,但只有最后一个键值对会被保留

相关词条

  • library-json-serialization JSON序列化高级技巧
  • library-json-custom-encoding 自定义JSON编码器
  • library-json-streaming JSON流式处理
  • library-json-validation JSON数据验证
  • library-json-vs-pickle JSON与pickle对比
  • langchain-tools LangChain工具调用中的JSON处理

官方原文:https://docs.python.org/zh-cn/3/library/json.html