跳到主要内容

json 模块

Python 内置的 json 模块主要提供 4 个常用方法,可以分成两组记忆:

方法作用操作对象
json.dumps()Python 对象 → JSON 字符串内存中的字符串
json.loads()JSON 字符串 → Python 对象内存中的字符串
json.dump()Python 对象 → JSON 文件文件
json.load()JSON 文件 → Python 对象文件

记忆技巧:带 s 的处理字符串 string,不带 s 的处理文件。

1. json.dumps():对象转 JSON 字符串​

import json

data = {"name": "张三", "age": 30, "tags": ["python", "ai"]}

json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)

输出:

{
"name": "张三",
"age": 30,
"tags": [
"python",
"ai"
]
}

常用参数:

  • ensure_ascii=False:保留中文,不转成 \uXXXX。
  • indent=2:缩进美化输出。
  • sort_keys=True:按 key 排序。
  • default=func:处理不可序列化的对象,比如 datetime。

2. json.loads():JSON 字符串转对象​

import json

json_str = '{"name": "Bob", "age": 25, "skills": ["java", "linux"]}'

obj = json.loads(json_str)
print(obj["name"]) # Bob
print(obj["skills"][0]) # java

如果字符串不是合法 JSON,会抛出 json.JSONDecodeError。

3. json.dump():对象写入 JSON 文件​

import json

data = {"product": "Laptop", "price": 8999, "in_stock": True}

with open("product.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)

它不会返回字符串,而是直接写入文件。

4. json.load():从文件读取 JSON​

import json

with open("product.json", "r", encoding="utf-8") as f:
obj = json.load(f)

print(obj)
print(type(obj)) # <class 'dict'>

类型对应关系​

Python 和 JSON 之间会做这些自动转换:

PythonJSON
dictobject
list / tuplearray
strstring
int / floatnumber
Truetrue
Falsefalse
Nonenull

进阶用法​

自定义序列化(default)​

json 只支持基础类型,遇到 datetime、自定义对象等会抛 TypeError。default 接收一个函数,遇到无法序列化的对象时调用它,返回可序列化的结果:

import json
from datetime import datetime

def to_json(obj):
if isinstance(obj, datetime):
return obj.strftime("%Y-%m-%d %H:%M:%S")
raise TypeError(f"不支持序列化: {type(obj)}")

json.dumps({"time": datetime.now()}, default=to_json)
# '{"time": "2026-10-23 16:30:00"}'

简单场景直接 default=str 也可以:json.dumps({"time": datetime.now()}, default=str)。

自定义反序列化(object_hook)​

object_hook 接收一个函数,每解析完一个 JSON object 都会调用它,适合在读取时做定制转换:

import json

def hook(d):
if "date" in d:
d["date"] = d["date"].replace("-", "/")
return d

obj = json.loads('{"date": "2026-10-23"}', object_hook=hook)
# {'date': '2026/10/23'}

编码器/解码器类​

需要复用同一套配置、或通过继承定制行为时,用 JSONEncoder / JSONDecoder:

import json
from datetime import datetime

# 编码器:复用配置
encoder = json.JSONEncoder(ensure_ascii=False, sort_keys=True)
encoder.encode({"b": 2, "a": 1}) # '{"a": 1, "b": 2}'

decoder = json.JSONDecoder()
decoder.decode('{"a": 1}') # {'a': 1}

# 继承定制:处理 datetime
class MyEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, datetime):
return o.isoformat()
return super().default(o)

json.dumps({"time": datetime.now()}, cls=MyEncoder)

日常用 dumps / loads 传参数即可,类只在复用或深度定制时使用。

异常处理​

json.loads 遇到非法 JSON 抛 json.JSONDecodeError;dumps 遇到不可序列化对象抛 TypeError。读取外部数据时建议捕获:

import json

try:
obj = json.loads("不是合法json")
except json.JSONDecodeError as e:
print(f"解析失败: {e.msg}, 第 {e.lineno} 行第 {e.colno} 列")

附:with open 怎么理解​

json.dump() / json.load() 操作文件时,推荐写法都是 with open(...) as f。这一行包含两部分:

open(...):打开文件,返回文件对象​

open("product.json", "r", encoding="utf-8")
参数值意思
第 1 个(文件路径)"product.json"要打开的文件
第 2 个(模式 mode)"r"read,只读(默认值);"w" 写入覆盖、"a" 追加
encoding"utf-8"按UTF-8 解码字节 → 文字,避免中文乱码

返回值是一个文件对象,是后续读写操作的"遥控器",此时还没有读取内容。

with ... as f:自动关闭文件​

with 的作用:代码块结束时自动执行 f.close(),即使中途报错也会关闭。

不用 with 的等价写法:

f = open("product.json", "r", encoding="utf-8")
try:
obj = json.load(f)
finally: # 无论成功失败都要手动关闭
f.close()

用 with 简化为:

with open("product.json", "r", encoding="utf-8") as f:
obj = json.load(f)
# 离开 with 代码块时,f 自动 close,不需要写 f.close()

as f 就是给文件对象起名字,在缩进代码块内通过 f 使用它。

常见注意​

  • 不能直接序列化 datetime、自定义对象、文件对象等,需要用 default 自定义转换。
  • 读取外部 JSON 时要做好异常处理,避免解析失败导致程序崩溃。
  • 中文数据建议始终加上 ensure_ascii=False,否则中文会变成 \uXXXX。