Python json解码器底层实现 Python json模块解码器底层实现json模块的JSONDecoder在CPython中用C实现_json加速模块。纯Python回退实现在json/decoder.py中。JSONDecoder的扫描过程import jsonfrom json.decoder import JSONDecoderdecoder JSONDecoder()result, idx decoder.raw_decode({key: value} extra)print(result) # {key: value}print(idx) # 17消耗的字符数raw_decode从指定位置开始解析返回解析结果结束位置。decoder.scan_once是底层扫描函数。它通过一个大的switch语句处理不同的JSON token类型。JSONEncoder的迭代编码encoder json.JSONEncoder()for chunk in encoder.iterencode({key: value}):print(chunk, end)# 逐步产生编码片段iterencode用于流式编码大对象。json.JSONEncoder的default方法处理不可序列化类型class CustomEncoder(json.JSONEncoder):def default(self, obj):if isinstance(obj, complex):return {__complex__: True, real: obj.real, imag: obj.imag}if isinstance(obj, datetime.datetime):return {__datetime__: True, value: obj.isoformat()}if isinstance(obj, Decimal):return str(obj)return super().default(obj)data {c: 34j, d: Decimal(10.5)}print(json.dumps(data, clsCustomEncoder))default在遇到不可序列化类型时被调用。如果default也无法处理抛出TypeError。object_hook和object_pairs_hookdef as_complex(dct):if __complex__ in dct:return complex(dct[real], dct[imag])return dctdata json.loads({val: {__complex__: true, real: 3, imag: 4}},object_hookas_complex)print(data) # {val: (34j)}object_hook在每个JSON对象解码后调用。object_pairs_hook同样但接收有序键值对列表。json.JSONEncoder的检查循环引用obj {}obj[self] objtry:json.dumps(obj)except ValueError as e:print(e) # Circular reference detectedJSONEncoder在编码时检测循环引用。通过_check_circular参数控制。json.dumps的separators参数控制紧凑输出compact json.dumps({key: value}, separators(,, :))print(compact) # {key:value}默认separators(, , : )。compact版本去掉空格。json.dump的ensure_ascii行为data {name: 中文}print(json.dumps(data)) # {name: 中文}print(json.dumps(data, ensure_asciiFalse)) # {name: 中文}ensure_asciiTrue时非ASCII字符被转义。False时输出原始Unicode。sort_keys按键排序data {c: 3, a: 1, b: 2}print(json.dumps(data, sort_keysTrue)) # {a: 1, b: 2, c: 3}JSONDecoder的strict参数控制控制字符# strictFalse允许控制字符\x00-\x1fjson.loads({key: value\x00}, strictFalse)json.tool命令行格式化# python -m json.tool input.json output.jsonJSONDecodeError的详细信息try:json.loads({invalid})except json.JSONDecodeError as e:print(fError at line {e.lineno}, col {e.colno}: {e.msg})print(fDocument: {e.doc})print(fPosition: {e.pos})