Python3 JSON 数据解析详解

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,简洁易读且跨语言兼容,在 Python 中处理 JSON 数据主要依赖内置的json模块。本文从基础到实战,详解 Python3 解析 JSON 的核心方法、常见场景和避坑技巧。

一、先搞懂:JSON 是什么?和 Python 数据类型有啥对应关系?

JSON 本质是一种字符串格式,用来表示结构化数据,比如:

{
  "name": "张三",
  "age": 25,
  "is_student": false,
  "hobbies": ["篮球", "编程"],
  "scores": {"math": 90, "english": 85}
}
 

它和 Python 数据类型的对应关系非常重要(转换时会自动映射):

JSON 类型Python 类型说明
对象({} 字典(dict 键值对集合
数组([] 列表(list 有序元素集合
字符串("" 字符串(str 必须用双引号(JSON 规范)
数字(整数) 整数(int 123123
数字(浮点数) 浮点数(float 3.143.14
true True 布尔值真
false False 布尔值假
null None 空值

二、核心工具:json模块的 4 个核心函数

Python 的json模块提供了 4 个核心函数,实现 “Python 对象↔JSON 字符串” 的相互转换:

函数作用适用场景
json.dumps() Python 对象→JSON 字符串(内存中转换) 需要在代码中处理 JSON 字符串时
json.dump() Python 对象→JSON 文件(直接写入文件) 需要将 JSON 保存到文件时
json.loads() JSON 字符串→Python 对象(内存中转换) 处理已获取的 JSON 字符串时
json.load() JSON 文件→Python 对象(直接读取文件) 读取 JSON 文件内容时

三、实战:从 Python 对象到 JSON(编码)

将 Python 的字典、列表等对象转换为 JSON 格式(称为 “编码”),用dumps()dump()

1. 基础用法:json.dumps()生成 JSON 字符串

 
import json

# 定义一个Python字典(包含多种类型)
data = {
    "name": "张三",
    "age": 25,
    "is_student": False,
    "hobbies": ["篮球", "编程"],
    "scores": {"math": 90, "english": 85},
    "address": None  # 对应JSON的null
}

# 将Python对象转为JSON字符串
json_str = json.dumps(data)
print(json_str)
# 输出:{"name": "\u5f20\u4e09", "age": 25, "is_student": false, "hobbies": ["\u7篮球", "\u7f16\u7a0b"], "scores": {"math": 90, "english": 85}, "address": null}
 

注意

  • 中文会被默认转为 Unicode 编码(如"张三""\u5f20\u4e09"),如需保留中文,加ensure_ascii=False参数:
     
    json_str = json.dumps(data, ensure_ascii=False)
    print(json_str)  # 中文正常显示
    
     
  • 生成的 JSON 字符串中,字符串必须用双引号(JSON 规范),Python 中的单引号会被自动转为双引号。

2. 美化 JSON:indentsort_keys参数

默认生成的 JSON 是紧凑的单行字符串,用indent设置缩进可美化格式,sort_keys=True可按键名排序:
 
 
json_str = json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True)
print(json_str)
 

输出(格式化后更易读):

{
  "address": null,
  "age": 25,
  "hobbies": [
    "篮球",
    "编程"
  ],
  "is_student": false,
  "name": "张三",
  "scores": {
    "english": 85,
    "math": 90
  }
}
 

3. 写入文件:json.dump()

如果需要将 JSON 数据保存到文件,直接用dump()更方便(无需先转字符串):
 
with open("data.json", "w", encoding="utf-8") as f:
    # 直接将Python对象写入文件,ensure_ascii=False保留中文
    json.dump(data, f, ensure_ascii=False, indent=2)
 

执行后会生成data.json文件,内容就是格式化后的 JSON。

四、实战:从 JSON 到 Python 对象(解码)

将 JSON 字符串或 JSON 文件转换为 Python 对象(称为 “解码”),用loads()load()

1. 解析 JSON 字符串:json.loads()

 
import json

# 定义一个JSON字符串(注意用双引号)
json_str = '''
{
  "name": "张三",
  "age": 25,
  "is_student": false,
  "hobbies": ["篮球", "编程"],
  "scores": {"math": 90, "english": 85},
  "address": null
}
'''

# 将JSON字符串转为Python对象(字典)
data = json.loads(json_str)
print(type(data))  # <class 'dict'>
print(data["name"])  # 张三
print(data["hobbies"][0])  # 篮球
print(data["scores"]["math"])  # 90
 

2. 读取 JSON 文件:json.load()

直接读取 JSON 文件并转换为 Python 对象:
 
with open("data.json", "r", encoding="utf-8") as f:
    data = json.load(f)  # 直接从文件加载并转换
    print(data["age"])  # 25
 

五、高级场景:处理复杂类型(如日期、自定义对象)

JSON 仅支持基础数据类型(字符串、数字、布尔、数组、对象、null),如果 Python 对象包含datetime、自定义类等复杂类型,直接转换会报错。需要自定义 “编码器” 和 “解码器”。

1. 处理datetime类型(编码)

JSON 不支持datetime,需转为字符串(如 ISO 格式)再编码:
 
 
import json
from datetime import datetime

# 定义包含datetime的Python对象
data = {
    "name": "张三",
    "birthdate": datetime(1999, 10, 1)
}

# 自定义编码器:将datetime转为ISO字符串
class DateTimeEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()  # 转为"1999-10-01T00:00:00"
        return super().default(obj)  # 其他类型用默认处理

# 用自定义编码器转换
json_str = json.dumps(data, cls=DateTimeEncoder, ensure_ascii=False)
print(json_str)
# 输出:{"name": "张三", "birthdate": "1999-10-01T00:00:00"}
 

2. 解析datetime字符串(解码)

将 JSON 中的日期字符串转回datetime对象:
 
 
from datetime import datetime

# 定义JSON字符串(包含日期字符串)
json_str = '{"name": "张三", "birthdate": "1999-10-01T00:00:00"}'

# 自定义解码器:将字符串转为datetime
def datetime_decoder(obj):
    if "birthdate" in obj:
        obj["birthdate"] = datetime.fromisoformat(obj["birthdate"])
    return obj

# 用object_hook参数指定解码器
data = json.loads(json_str, object_hook=datetime_decoder)
print(type(data["birthdate"]))  # <class 'datetime.datetime'>
print(data["birthdate"].year)  # 1999
 

六、避坑指南:常见错误与解决

  1. JSON 字符串格式错误(最常见)
    错误:JSON 中用单引号(如{'name': '张三'}),或键不是字符串(如{123: "value"})。
    解决:严格遵守 JSON 规范 —— 字符串用双引号,键必须是字符串。
  2. 解析无效 JSON 时的报错
    错误:json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes
    解决:检查 JSON 格式,用try-except捕获错误:
    try:
        data = json.loads(invalid_json_str)
    except json.JSONDecodeError as e:
        print(f"JSON解析错误:{e}")
    
     
  3. 复杂类型未处理导致的编码错误
    错误:TypeError: Object of type datetime is not JSON serializable
    解决:自定义编码器(如上文的DateTimeEncoder),将复杂类型转为基础类型。

七、总结

Python 处理 JSON 的核心是json模块的 4 个函数:

  • 编码(Python→JSON):dumps()(转字符串)、dump()(写文件);
  • 解码(JSON→Python):loads()(解析字符串)、load()(读文件)。

关键注意点:

  • 牢记 JSON 与 Python 类型的对应关系;
  • 中文处理需加ensure_ascii=False
  • 复杂类型(如datetime)需自定义编码 / 解码器;
  • 严格遵守 JSON 格式规范,避免解析错误。

posted on 2025-09-02 14:59  小陶coding  阅读(228)  评论(0)    收藏  举报