Python JSON模块详解:从入门到高级应用

Python JSON模块详解:从入门到高级应用

一、初识JSON与Python的json模块

1. 什么是JSON?

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,具有以下特点:

  • 人类可读的文本格式
  • 独立于编程语言(Python/Java/JavaScript等都能处理)
  • 结构清晰:键值对集合(对象)和有序值列表(数组)

示例比较XML与JSON:

xml 复制代码
<!-- XML格式 -->
<user>
  <name>张三</name>
  <age>25</age>
  <skills>
    <skill>Python</skill>
    <skill>Java</skill>
  </skills>
</user>
json 复制代码
// JSON格式
{
  "name": "张三",
  "age": 25,
  "skills": ["Python", "Java"]
}

2. 为什么需要json模块?

  • 网络传输:Web API数据交换(如微信接口)
  • 配置文件:存储程序设置信息
  • 数据持久化:简单数据存储
  • 跨语言协作:与JavaScript/Java等其他语言交互

3. 基础数据类型对照表

Python类型 JSON类型
dict object
list array
str string
int/float number
True/False true/false
None null

二、基础操作步步学

1. 模块导入与基本方法

python 复制代码
import json

# 核心方法清单
print([func for func in dir(json) if not func.startswith('_')])
# 输出:['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', 'dump', 'dumps', 'load', 'loads']

2. 序列化操作(Python → JSON)

python 复制代码
# 创建示例数据
data = {
    "project": "天气预报系统",
    "version": 1.2,
    "authors": ["张三", "李四"],
    "stable": True,
    "config": None
}

# 基本序列化
json_str = json.dumps(data)
print(type(json_str))  # <class 'str'>
print(json_str) 
# {"project": "\u5929\u6c14\u9884\u62a5\u7cfb\u7edf", "version": 1.2, ...}

# 解决中文乱码问题
json_str_chinese = json.dumps(data, ensure_ascii=False)
print(json_str_chinese)
# {"project": "天气预报系统", ...}

3. 反序列化操作(JSON → Python)

python 复制代码
# 基本反序列化
restored_data = json.loads(json_str_chinese)
print(type(restored_data))  # <class 'dict'>
print(restored_data["authors"])  # ['张三', '李四']

# 验证数据一致性
assert restored_data == data  # 无报错说明数据一致

4. 文件读写操作

python 复制代码
# 写入JSON文件
with open("config.json", "w", encoding="utf-8") as f:
    json.dump(data, f, indent=2, ensure_ascii=False)

# 读取JSON文件
with open("config.json", "r", encoding="utf-8") as f:
    file_data = json.load(f)

print(file_data["project"])  # 天气预报系统

三、参数详解与实用技巧

1. dumps常用参数演示

python 复制代码
# 美观格式化输出
print(json.dumps(data, indent=4, ensure_ascii=False))
"""
{
    "project": "天气预报系统",
    "version": 1.2,
    "authors": [
        "张三",
        "李四"
    ],
    "stable": true,
    "config": null
}
"""

# 键排序与紧凑格式
print(json.dumps(data, sort_keys=True, separators=(',', ':')))
# {"authors":["张三","李四"],"config":null,"project":"天气预报系统","stable":true,"version":1.2}

2. 特殊数据类型处理

python 复制代码
# 处理日期时间
from datetime import datetime

event = {
    "title": "项目启动会",
    "time": datetime(2023, 8, 25, 14, 30)
}

# 直接序列化会报错!
# json.dumps(event)  # TypeError: Object of type datetime is not JSON serializable

# 自定义处理函数
def datetime_handler(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError("无法序列化的类型")

print(json.dumps(event, default=datetime_handler, ensure_ascii=False))
# {"title": "项目启动会", "time": "2023-08-25T14:30:00"}

四、面向对象编程实战

1. 自定义类序列化

python 复制代码
class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score
        
    def __repr__(self):
        return f"<Student {self.name} [{self.score}]>"

# 创建实例
stu = Student("王五", 95)

# 方案1:自定义转换函数
def student_encoder(obj):
    if isinstance(obj, Student):
        return {"name": obj.name, "score": obj.score}
    raise TypeError

json_str = json.dumps(stu, default=student_encoder, ensure_ascii=False)
print(json_str)  # {"name": "王五", "score": 95}

# 方案2:继承JSONEncoder
class MyEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Student):
            return {"name": obj.name, "score": obj.score}
        return super().default(obj)

print(json.dumps(stu, cls=MyEncoder))  # {"name": "王五", "score": 95}

2. 自定义类反序列化

python 复制代码
# 反序列化处理函数
def student_decoder(dct):
    if "name" in dct and "score" in dct:
        return Student(dct["name"], dct["score"])
    return dct

# 反序列化操作
restored_stu = json.loads(json_str, object_hook=student_decoder)
print(type(restored_stu))  # <class '__main__.Student'>
print(restored_stu)  # <Student 王五 >

五、错误处理与调试技巧

1. 常见错误类型

python 复制代码
# 格式错误示例
invalid_json = '{"name": "张三", "age": 25,}'

try:
    json.loads(invalid_json)
except json.JSONDecodeError as e:
    print(f"错误位置:第{e.lineno}行第{e.colno}列")
    print(f"错误详情:{e.msg}")
    # 错误位置:第1行第25列
    # 错误详情:Expecting property name enclosed in double quotes

2. 调试技巧

python 复制代码
# 使用pprint查看数据结构
from pprint import pprint

complex_data = {
    "users": [
        {"name": "张三", "contacts": {"email": "zhangsan@example.com", "phone": "13800138000"}},
        {"name": "李四", "contacts": {"email": "lisi@example.com"}}
    ]
}

pprint(json.loads(json.dumps(complex_data)))
"""
{'users': [{'contacts': {'email': 'zhangsan@example.com', 'phone': '13800138000'},
            'name': '张三'},
           {'contacts': {'email': 'lisi@example.com'}, 'name': '李四'}]}
"""

六、综合应用案例

1. 模拟Web API交互

python 复制代码
import requests  # 需先安装:pip install requests

# 获取公开API数据
response = requests.get("https://api.github.com/users/octocat")
api_data = response.json()

# 提取关键信息
processed = {
    "username": api_data["login"],
    "name": api_data["name"],
    "followers": api_data["followers"]
}

# 保存到本地
with open("github_user.json", "w") as f:
    json.dump(processed, f, indent=2)

print(open("github_user.json").read())
"""
{
  "username": "octocat",
  "name": "The Octocat",
  "followers": 7940
}
"""

七、最佳实践与注意事项

安全警示

  • 不要反序列化不可信来源的JSON数据
  • 使用object_hook时验证数据完整性

性能优化

  • 处理大文件时使用json.load()替代json.loads()
  • 设置合理的indent参数(生产环境通常不使用)

编码规范

  • 统一使用UTF-8编码
  • 保持键名的一致性(如全小写加下划线)

扩展建议

  • 使用simplejson库处理更复杂的需求
  • 结合jsonschema验证JSON格式
python 复制代码
# 扩展:使用类型注解(Python 3.9+)
from typing import TypedDict

class UserData(TypedDict):
    name: str
    age: int

def validate_user(data: UserData):
    if not isinstance(data["age"], int):
        raise ValueError("年龄必须是整数")

user = json.loads('{"name": "张三", "age": 25}')
validate_user(user)

通过本文的学习,你已经掌握了JSON模块的核心用法。记住:多动手实践、遇到错误仔细阅读提示信息、善用Python的文档资源(help(json.JSONEncoder)),你就能在项目中游刃有余地处理JSON数据啦!

复制代码
相关推荐
上单带刀不带妹6 分钟前
手写 Vue 中虚拟 DOM 到真实 DOM 的完整过程
开发语言·前端·javascript·vue.js·前端框架
im_AMBER26 分钟前
学习日志05 python
python·学习
大虫小呓31 分钟前
Python 处理 Excel 数据 pandas 和 openpyxl 哪家强?
python·pandas
哪 吒43 分钟前
2025B卷 - 华为OD机试七日集训第5期 - 按算法分类,由易到难,循序渐进,玩转OD(Python/JS/C/C++)
python·算法·华为od·华为od机试·2025b卷
-凌凌漆-1 小时前
【Qt】QStringLiteral 介绍
开发语言·qt
程序员爱钓鱼1 小时前
Go语言项目工程化 — 常见开发工具与 CI/CD 支持
开发语言·后端·golang·gin
axinawang1 小时前
极域电子教室出现问题如何处理
经验分享
军训猫猫头1 小时前
1.如何对多个控件进行高效的绑定 C#例子 WPF例子
开发语言·算法·c#·.net
真的想上岸啊2 小时前
学习C++、QT---18(C++ 记事本项目的stylesheet)
开发语言·c++·学习
明天好,会的2 小时前
跨平台ZeroMQ:在Rust中使用zmq库的完整指南
开发语言·后端·rust