结合你的学习需求,我会把 json 模块的 4 个核心函数
| 函数 | 方向 | 操作对象 | 核心参数(新手必设) |
|---|---|---|---|
json.dumps |
Python 对象 → JSON 字符串 | 内存数据 | ensure_ascii=False、indent=4 |
json.loads |
JSON 字符串 → Python 对象 | 内存字符串 | object_hook(自定义解析) |
json.dump |
Python 对象 → JSON 文件 | 文件 | ensure_ascii=False、encoding="utf-8" |
json.load |
JSON 文件 → Python 对象 | 文件 | encoding="utf-8" |
前置准备: Python 内置 json 模块,无需安装,使用前只需导入:
python
import json
一、内存级转换:处理 JSON 字符串 ↔ Python 对象
这类函数只在内存中操作数据(不涉及文件),适合接口传参、数据临时转换等场景。
1. json.dumps ():Python 对象 → JSON 字符串
核心功能: 将 Python 字典、列表、字符串等合法对象,转换成符合 JSON 语法的字符串(本质是 Python 字符串类型)。
函数原型
python
json.dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
default=None, sort_keys=False, **kw)
关键参数详解(新手必掌握)
| 参数名 | 作用 | 默认值 | 实用示例 |
|---|---|---|---|
obj |
要转换的 Python 对象(必须是可序列化类型:dict/list/str/int/float/bool/None) | - | {"name":"张三"} |
ensure_ascii |
是否强制用 ASCII 编码(False = 保留中文 ,不转成 \uXXXX 格式) |
True | ensure_ascii=False |
indent |
格式化缩进(数字 = 缩进空格数,None = 紧凑格式) | None | indent=4(开发常用) |
sort_keys |
是否按字母顺序排序 JSON 对象的键 | False | sort_keys=True |
separators |
自定义分隔符(元组格式:(分隔符 1, 分隔符 2),用于精简 JSON 字符串) | None | separators=(',', ':') |
default |
自定义序列化函数(处理不可序列化对象,如 datetime) | None | 见下方示例 |
完整使用示例
python
import json
from datetime import datetime # 用于演示自定义序列化
# 1. 基础用法(保留中文+格式化)
python_data = {
"name": "张三",
"age": 18,
"is_student": True,
"hobbies": ["篮球", "游戏"],
"score": None,
"register_time": datetime.now() # 不可直接序列化的对象
}
# 自定义序列化函数:处理 datetime 类型
def serialize_datetime(obj):
if isinstance(obj, datetime):
return obj.strftime("%Y-%m-%d %H:%M:%S")
raise TypeError(f"无法序列化 {type(obj)} 类型")
# 转换为 JSON 字符串
json_str = json.dumps(
python_data,
ensure_ascii=False, # 保留中文
indent=4, # 缩进4空格,格式化输出
sort_keys=True, # 按键排序
default=serialize_datetime # 处理 datetime
)
# 输出结果
print("JSON 字符串:")
print(json_str)
print("类型验证:", type(json_str)) # <class 'str'>
# 2. 精简格式(无缩进+自定义分隔符)
compact_json = json.dumps(
python_data,
ensure_ascii=False,
indent=None, # 紧凑空格
separators=(',', ':'), # 去掉键值对之间的空格
default=serialize_datetime
)
print("\n精简版 JSON 字符串:")
print(compact_json)
输出结果
python
JSON 字符串:
{
"age": 18,
"hobbies": [
"篮球",
"游戏"
],
"is_student": true,
"name": "张三",
"register_time": "2026-03-18 15:30:00",
"score": null
}
类型验证: <class 'str'>
精简版 JSON 字符串:
{"age":18,"hobbies":["篮球","游戏"],"is_student":true,"name":"张三","register_time":"2026-03-18 15:30:00","score":null}
注意事项
- 不是所有 Python 对象都能序列化:比如 datetime、set、自定义类实例 ,需通过
default参数自定义处理; - 布尔值
True/False会自动转为true/false,None转为null; - 列表 / 元组都会被序列化为 JSON 数组(
[])。
2. json.loads ():JSON 字符串 → Python 对象
核心功能:将合法的 JSON 字符串,转换成对应的 Python 对象(字典 / 列表 / 字符串等)。
函数原型
python
json.loads(s, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
关键参数详解
| 参数名 | 作用 | 默认值 | 实用示例 |
|---|---|---|---|
s |
要解析的 JSON 字符串(必须是 str/bytes/bytearray 类型) | - | '{"name":"张三"}' |
object_hook |
自定义反序列化函数(将 JSON 对象转为自定义类实例) | None | 见下方示例 |
parse_float |
自定义浮点数解析函数(比如将浮点数转为 Decimal) | None | parse_float=Decimal |
parse_int |
自定义整数解析函数(比如将大整数转为 int64) | None | parse_int=np.int64 |
完整使用示例
python
import json
from datetime import datetime
from decimal import Decimal # 用于高精度浮点数解析
# 1. 基础用法
json_str = '''
{
"name": "张三",
"age": 18,
"is_student": true,
"hobbies": ["篮球", "游戏"],
"score": null,
"register_time": "2026-03-18 15:30:00"
}
'''
# 转换为 Python 对象
python_data = json.loads(json_str)
# 验证类型和取值
print("转换后的 Python 对象类型:", type(python_data)) # <class 'dict'>
print("姓名:", python_data["name"]) # 张三
print("年龄:", python_data["age"]) # 18
print("爱好:", python_data["hobbies"][0]) # 篮球
# 2. 自定义反序列化:将字符串时间转回 datetime
def deserialize_datetime(obj):
if "register_time" in obj:
obj["register_time"] = datetime.strptime(obj["register_time"], "%Y-%m-%d %H:%M:%S")
return obj
# 带自定义钩子的解析
python_data_custom = json.loads(
json_str,
object_hook=deserialize_datetime, # 处理 JSON 对象
parse_float=Decimal # 浮点数解析为 Decimal(高精度)
)
print("\n自定义解析后的时间类型:", type(python_data_custom["register_time"])) # <class 'datetime.datetime'>
# 3. 解析 JSON 数组字符串
json_arr_str = '["张三", 18, true, null]'
python_arr = json.loads(json_arr_str)
print("\n数组解析结果:", python_arr) # ['张三', 18, True, None]
print("数组元素类型:", type(python_arr[2])) # <class 'bool'>
输出结果
python
转换后的 Python 对象类型: <class 'dict'>
姓名: 张三
年龄: 18
爱好: 篮球
自定义解析后的时间类型: <class 'datetime.datetime'>
数组解析结果: ['张三', 18, True, None]
数组元素类型: <class 'bool'>
注意事项
- JSON 字符串必须合法:比如键必须用双引号、布尔值小写、无多余逗号,否则报
JSONDecodeError; - 解析后:
true→True、false→False、null→None、[]→list、{}→dict; - 若 JSON 字符串是 bytes 类型(如接口返回),需先解码为 str:
json.loads(bytes_str.decode("utf-8"))。
二、文件级操作:处理 JSON 文件 ↔ Python 对象
这类函数直接读写文件,是实际开发中最常用的场景(如保存配置、存储数据)。
3. json.dump ():Python 对象 → 写入 JSON 文件
核心功能:将 Python 对象直接写入 JSON 文件(无需先转字符串),一步完成序列化 + 文件写入。
函数原型
python
json.dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
default=None, sort_keys=False, **kw)
关键参数详解(新增 / 重点)
| 参数名 | 作用 | 默认值 |
|---|---|---|
obj |
要序列化的 Python 对象(同 dumps) | - |
fp |
文件对象(必须以可写模式打开,如 open("file.json", "w", encoding="utf-8")) |
- |
| 其他参数 | 同 dumps(ensure_ascii/indent/sort_keys 等) |
同 dumps |
完整使用示例
python
import json
from datetime import datetime
# 准备数据
python_data = {
"users": [
{"id": 1, "name": "张三", "age": 18, "register_time": datetime.now()},
{"id": 2, "name": "李四", "age": 20, "register_time": datetime.now()}
],
"update_time": datetime.now()
}
# 自定义序列化函数:处理 datetime
def serialize_dt(obj):
if isinstance(obj, datetime):
return obj.strftime("%Y-%m-%d %H:%M:%S")
raise TypeError(f"无法序列化 {type(obj)}")
# 1. 基础写入(保留中文+格式化)
with open("users.json", "w", encoding="utf-8") as f:
json.dump(
python_data,
f,
ensure_ascii=False, # 保留中文
indent=4, # 格式化缩进
default=serialize_dt # 处理 datetime
)
print("基础写入完成:生成 users.json 文件")
# 2. 精简写入(无缩进,减小文件体积)
with open("users_compact.json", "w", encoding="utf-8") as f:
json.dump(
python_data,
f,
ensure_ascii=False,
indent=None,
separators=(',', ':'), # 精简分隔符
default=serialize_dt
)
print("精简写入完成:生成 users_compact.json 文件")
生成的 users.json 文件内容
python
{
"users": [
{
"id": 1,
"name": "张三",
"age": 18,
"register_time": "2026-03-18 15:40:00"
},
{
"id": 2,
"name": "李四",
"age": 20,
"register_time": "2026-03-18 15:40:00"
}
],
"update_time": "2026-03-18 15:40:00"
}
注意事项
- 文件必须指定编码:
encoding="utf-8",否则中文会乱码; - 打开模式:用
w(覆盖写入)或a(追加,但追加后 JSON 会不合法,不推荐); - 若写入超大文件,建议分块处理,避免内存溢出。
4. json.load ():从 JSON 文件 → 读取为 Python 对象
核心功能:直接从 JSON 文件读取内容,并转换为对应的 Python 对象(无需手动读文件)。
函数原型
python
json.load(fp, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
关键参数详解(新增 / 重点)
| 参数名 | 作用 | 默认值 |
|---|---|---|
fp |
文件对象(必须以可读模式打开,如 open("file.json", "r", encoding="utf-8")) |
- |
| 其他参数 | 同 loads(object_hook/parse_float 等) |
同 loads |
完整使用示例
python
import json
from datetime import datetime
from decimal import Decimal
# 1. 基础读取
with open("users.json", "r", encoding="utf-8") as f:
python_data = json.load(f)
# 验证读取结果
print("读取的文件数据类型:", type(python_data)) # <class 'dict'>
print("第一个用户姓名:", python_data["users"][0]["name"]) # 张三
print("更新时间:", python_data["update_time"]) # 2026-03-18 15:40:00
# 2. 自定义反序列化:恢复 datetime 类型
def deserialize_dt(obj):
# 处理用户注册时间
if "register_time" in obj:
obj["register_time"] = datetime.strptime(obj["register_time"], "%Y-%m-%d %H:%M:%S")
# 处理整体更新时间
if "update_time" in obj:
obj["update_time"] = datetime.strptime(obj["update_time"], "%Y-%m-%d %H:%M:%S")
return obj
with open("users.json", "r", encoding="utf-8") as f:
python_data_custom = json.load(
f,
object_hook=deserialize_dt, # 自定义反序列化
parse_float=Decimal # 浮点数解析为 Decimal
)
# 验证自定义解析结果
print("\n第一个用户注册时间类型:", type(python_data_custom["users"][0]["register_time"])) # <class 'datetime.datetime'>
print("更新时间类型:", type(python_data_custom["update_time"])) # <class 'datetime.datetime'>
# 3. 读取 JSON 数组文件(假设 array.json 内容是 ["张三", 18, true])
with open("array.json", "w", encoding="utf-8") as f:
json.dump(["张三", 18, True], f, ensure_ascii=False)
with open("array.json", "r", encoding="utf-8") as f:
arr_data = json.load(f)
print("\n数组文件读取结果:", arr_data) # ['张三', 18, True]
输出结果
python
读取的文件数据类型: <class 'dict'>
第一个用户姓名: 张三
更新时间: 2026-03-18 15:40:00
第一个用户注册时间类型: <class 'datetime.datetime'>
更新时间类型: <class 'datetime.datetime'>
数组文件读取结果: ['张三', 18, True]
注意事项
- 文件必须存在且可读:否则报
FileNotFoundError; - 文件编码必须匹配:读取时的
encoding要和写入时一致(推荐统一用utf-8); - 若文件内容是空或非法 JSON,报
JSONDecodeError,建议加异常处理。
三、实战:异常处理(必加!)
实际开发中,必须处理可能的错误,以下是通用模板:
python
import json
def safe_load_json_file(file_path):
"""安全读取 JSON 文件的函数"""
try:
with open(file_path, "r", encoding="utf-8") as f:
return json.load(f)
except FileNotFoundError:
print(f"错误:文件 {file_path} 不存在!")
return None
except json.JSONDecodeError as e:
print(f"错误:JSON 格式非法 → {e}")
return None
except PermissionError:
print(f"错误:无权限读取 {file_path}!")
return None
except Exception as e:
print(f"未知错误:{e}")
return None
def safe_dump_json_file(file_path, data):
"""安全写入 JSON 文件的函数"""
try:
with open(file_path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=4)
print(f"数据已成功写入 {file_path}")
return True
except PermissionError:
print(f"错误:无权限写入 {file_path}!")
return False
except TypeError as e:
print(f"错误:数据无法序列化 → {e}")
return False
except Exception as e:
print(f"未知错误:{e}")
return False
# 调用示例
data = {"name": "张三"}
safe_dump_json_file("test.json", data)
loaded_data = safe_load_json_file("test.json")
- 处理中文必加
ensure_ascii=False+ 文件编码utf-8; - 格式化输出用
indent=4,精简文件用indent=None + separators=(',', ':'); - 非标准类型(datetime/set)需用
default(序列化)/object_hook(反序列化)自定义处理; - 所有文件操作必须加异常处理,避免程序崩溃。