page contents

七个 Python 处理 JSON 的高级技巧,尤其是超大文件解析,看完有收获

很多人觉得 JSON 处理就是 json.loads 和 json.dumps 两下搞定。实际遇到几百 MB 甚至上 G 的文件时,电脑直接卡死。我踩过不少坑,今天把七个实战技巧掏出来分享给你。

attachments-2026-08-qSQIHfWa6a753d8a25ae2.png很多人觉得 JSON 处理就是 json.loads 和 json.dumps 两下搞定。实际遇到几百 MB 甚至上 G 的文件时,电脑直接卡死。我踩过不少坑,今天把七个实战技巧掏出来分享给你。

1. 用流式解析代替一次性加载

普通 json.load 会把整个文件读到内存里。碰到 2GB 的日志文件,32GB 内存的机器也会爆。改用 ijson 库,它像个水龙头一样一点点放数据。安装命令是 pip install ijson。用法示例:

import ijson

with open('huge.json', 'r') as f:

   parser = ijson.parse(f)

   for prefix, event, value in parser:

       if event == 'map_key':

           print(f'Key: {value}')

这样每处理一个键值对就释放一次内存,不会把整个文件压进内存。

2. 按块处理嵌套数组

假设 JSON 文件里有一个超大数组,每个元素都是一个对象。用 ijson.items 可以按元素逐个处理。比如数据长这样:{'data': [{'id':1}, {'id':2}, ...]}。代码如下:

import ijson

with open('array.json', 'r') as f:

   for item in ijson.items(f, 'data.item'):

        每次只处理一个数组元素

       process(item)

每个元素处理完就可以丢掉,内存占用始终很小。

3. 用 orjson 提速 10 倍

标准库 json 对于高频或者大量小文件场景很慢。试试 orjson,它底层用 Rust 写的,解析速度快 10 倍以上。安装 pip install orjson。用法几乎一样:

import orjson

with open('data.json', 'rb') as f:

   data = orjson.loads(f.read())

    注意传入的是 bytes,不是字符串

输出时也可以直接 orjson.dumps(data)。它默认把中文按字节码处理,速度更快。

4. 遇到格式不规范的 JSON 用 json_util 或 demjson

现实中的 JSON 经常混着单引号、多余逗号、注释。标准库非常严格,一遇到就会报错。用 demjson 可以容忍这些小毛病。安装 pip install demjson。示例:

import demjson

text = '{'name': '张三', 'score': 95, }'   单引号+多余逗号

data = demjson.decode(text)

print(data)   可以正常输出

注意 demjson 版本较老,Python 3.9 以上可能不兼容,可以用 jsonlines 替代处理行格式混乱的数据。

5. 用 jsonlines 处理每行一个 JSON

很多日志文件格式是每行一个 JSON 对象,没有逗号分隔。直接 json.load 会出错。用 jsonlines 库专门处理这种格式。安装 pip install jsonlines。用法:

import jsonlines

with jsonlines.open('log.jsonl') as reader:

   for obj in reader:

        逐行处理每个 JSON

       print(obj['timestamp'])

它自动处理换行和编码问题,特别适合日志分析。

6. 大文件写回时用 iterencode 或分块写入

处理完大 JSON 后要写回文件,千万别一次性构建整个字符串。用 json.JSONEncoder 的迭代器模式。标准库里的 json.JSONEncoder().iterencode(data) 可以逐块输出字符串。实战代码:

import json

data = [{'id': i} for i in range(1000000)]

with open('output.json', 'w', encoding='utf-8') as f:

   for chunk in json.JSONEncoder().iterencode(data):

       f.write(chunk)

这样可以避免内存中一次性生成巨量字符串,写入大文件时很稳。

7. 自定义序列化处理复杂对象

遇到 Python 自定义类或者 datetime 对象,直接 json.dumps 会报错。写一个 default 函数来处理。比如:

import json

from datetime import datetime

class User:

   def __init__(self, name, join_time):

       self.name = name

       self.join_time = join_time

def custom_serializer(obj):

   if isinstance(obj, datetime):

       return obj.isoformat()

   if isinstance(obj, User):

       return {'name': obj.name, 'join_time': obj.join_time}

   raise TypeError(f'Type {type(obj)} not serializable')

user = User('小明', datetime.now())

json_str = json.dumps(user, default=custom_serializer, ensure_ascii=False)

print(json_str)

如果用 orjson,它自带对 datetime 的支持,但自定义对象也得写 default 参数。这块灵活点能省很多调试时间。

这些技巧都是我真刀真枪用过的。最开始处理 800MB 的爬虫数据,内存不够用,卡了半小时。后来换成流式解析几秒跑完。如果你也遇到过类似问题,试试上面几个方法。手边没环境可以先收藏,用到时照着写就行。

更多相关技术内容咨询欢迎前往并持续关注好学星城论坛了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

2299 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. Pack 2299 文章
  3. 小柒 2228 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章