一文读懂 Python 的 JSON 模块:从零到高手的进阶之路

0 阅读5分钟

💡 开篇聊聊:为什么 JSON 这么重要?

你有没有发现,现在我们写 Python,几乎绕不开一个东西:JSON

打开一个 API 接口,返回的是 JSON; 翻个配置文件,存储的是 JSON; 甚至你写个爬虫,扒下来的数据,十有八九也是 JSON。

可以说,JSON 就像数据世界的“英语”,谁都得懂点。

而在 Python 里,处理 JSON 的关键武器就是自带的 json 模块。

很多人以为这东西很简单:不就是 dumpsloads 吗?但真要用到复杂业务时,才会发现——里面藏着不少细节和坑。

今天我就带你,从最简单的入门,到高级的定制玩法,再到一些实战中的坑和小技巧,把 json 模块聊透。

这不是“搬运文档”,而是把它放到真实开发场景里讲,让你学了就能用,且心里有数。

wechat_2025-08-23_105457_925.png


🚀 第一层:最基础的编码和解码

所有关于 JSON 的操作,基本都绕不开两个函数:

  • json.dumps() —— 把 Python 对象转成 JSON 字符串
  • json.loads() —— 把 JSON 字符串转回 Python 对象

看个例子:

import json

# Python 字典转换为 JSON 字符串
data = {"name""Alice""age"25"is_student"False}
json_str = json.dumps(data)
print(json_str)  # 输出: {"name": "Alice", "age": 25, "is_student": false}

# JSON 字符串转换回 Python 字典
python_dict = json.loads(json_str)
print(python_dict["name"])  # 输出: Alice

是不是很直观?

不过注意了:

  • Python 的 True / False 会被转成 true / false
  • Python 的 None 会变成 null
  • 而像集合、函数、类这种东西,默认是没法直接转的

这就像你要翻译语言,有些词能直译,有些就得解释甚至“改写”。


🚀 第二层:文件操作,别再傻乎乎自己写读写了

真实项目里,JSON 更多的不是存在内存里,而是保存在文件中。比如:

  • 网站的配置文件
  • 存储爬虫抓到的数据
  • 或者日志和缓存

如果你用 dumpswrite,或者 readloads,那就太麻烦了。

Python 早就贴心地给你准备了两个函数:

  • json.dump() —— 直接把对象写入文件
  • json.load() —— 直接从文件读出 JSON

看例子:

import json

# 将数据写入 JSON 文件
data = {"users": ["Alice""Bob""Charlie"], "count"3}
with open("data.json""w"as f:
    json.dump(data, f)

# 从 JSON 文件读取数据
with open("data.json""r"as f:
    loaded_data = json.load(f)
    print(loaded_data["users"])  # 输出: ['Alice', 'Bob', 'Charlie']

一句话总结:

dumps/loads 是处理字符串的, dump/load 是处理文件的。


🚀 第三层:复杂对象怎么搞?

问题来了,假设你有一个自定义的类,比如用户对象,里面还有 datetime 时间字段。

默认序列化肯定报错,因为 JSON 根本不认识这些类型。

这时候就要用到 defaultobject_hook 参数,来自定义序列化/反序列化逻辑。

from datetime import datetime
import json

class User:
    def __init__(self, name, join_date):
        self.name = name
        self.join_date = join_date

# 自定义序列化函数
def user_encoder(obj):
    if isinstance(obj, User):
        return {"name": obj.name, "join_date": obj.join_date.isoformat()}
    elif isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")

# 创建并序列化复杂对象
user = User("Alice", datetime.now())
json_str = json.dumps(user, default=user_encoder)
print(json_str)  # 输出包含用户信息和日期的 JSON 字符串

这样,你就能“教会” JSON 该怎么理解你的类。

这一点在实际开发里太重要了,不然很多复杂数据根本保存不下来。


🚀 第四层:美观 vs 性能,两全其美

有时候,你要把 JSON 打印出来给人看,那必须排版整齐,不然眼睛要瞎;

但有时候,你是要把 JSON 传到网络上,数据越紧凑越好,不然带宽压力大。

这就用到 indentseparatorssort_keys 这些参数了。

data = {"name""Alice""skills": ["Python""SQL""Data Analysis"], "age"28}

# 美化输出,适合人类阅读
pretty_json = json.dumps(data, indent=4, sort_keys=True)
print(pretty_json)

# 优化输出,减少空格,适合网络传输
compact_json = json.dumps(data, separators=(","":"))
print(compact_json)

这就像两种不同的“写作文”风格:

  • 给老师看的,排版整齐,字迹工整
  • 给自己看的,速记,越省空间越好

场景不同,写法就不同。


🚀 第五层:实战中的坑和小技巧

很多人以为学了上面四层就完事了,结果一到实战就翻车。这里我总结几个常见坑:

1. JSON 解析错误

malformed_json = '{"name": "Alice", "age": }'  # 缺少值

try:
    data = json.loads(malformed_json)
except json.JSONDecodeError as e:
    print(f"JSON 解析错误: {e}")

别让程序直接崩掉,记得用 JSONDecodeError 去兜底。

2. Unicode 问题

中文经常会被转成 \u4e2d\u6587 这种,看着很烦。解决办法:

json.dumps(data, ensure_ascii=False)

3. 浮点数精度

有些场景对数字精度很敏感,注意 JSON 可能把 1.00000001 变成 1.0。

4. 循环引用

比如一个对象引用了自己,会无限递归报错。这种情况得小心数据结构,别瞎转。


🚀 最后一层:心法

其实,学工具不是目的。

真正的高手,关注的不只是“怎么用”,而是:

  • 什么时候该用 JSON?
  • 怎么让 JSON 更高效?
  • 怎么保证安全,不被奇怪的输入搞崩?

就像会开车,不只是会踩油门刹车,更是懂得什么时候该开快,什么时候该减速。

所以,当你下次处理 JSON 时,可以多问自己几个问题:

  • 这个数据会不会特别大?
  • 要不要给人看?要不要美化?
  • 有没有潜在的安全风险?

带着这些思考去实践,你才会真的进阶。


🔥 总结

今天我们一路走下来,从最基础的 dumps / loads,到文件操作 dump / load,再到复杂对象、格式优化、常见陷阱。

掌握这些,你基本可以应付 90% 的场景了。剩下的 10%,需要你在实战中不断踩坑,不断优化。

记住:

  • JSON 是数据世界的通用语言
  • json 模块是 Python 的翻译官
  • 会用只是第一步,懂得“何时、为何、如何用”才是真正的高手

如果你读完觉得收获不小,不妨点个赞,或者分享给身边也在写 Python 的朋友。

毕竟,学会一个模块只是开始,用它打开更多的可能性,才是真正的进阶。