《Python解析JSON详解》
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,因其易读、易解析的特性被广泛应用于前后端数据交互、配置文件存储等场景。Python通过内置的`json`模块提供了对JSON数据的完整支持,包括序列化(将Python对象转为JSON字符串)和反序列化(将JSON字符串转为Python对象)。本文将系统讲解Python中JSON的解析方法、常见问题及高级应用。
一、JSON基础与Python类型映射
JSON数据由键值对(对象)、数组(列表)、字符串、数字、布尔值和`null`组成。Python中与之对应的类型如下:
JSON类型 | Python类型 |
---|---|
对象(Object) | dict |
数组(Array) | list |
字符串(String) | str |
数字(Number) | int/float |
布尔值(true/false) | True/False |
null | None |
二、JSON解析核心方法
1. json.loads():字符串转Python对象
将JSON格式的字符串解析为Python对象(dict/list等):
import json
json_str = '{"name": "Alice", "age": 25, "hobbies": ["reading", "hiking"]}'
data = json.loads(json_str)
print(data) # 输出: {'name': 'Alice', 'age': 25, 'hobbies': ['reading', 'hiking']}
print(type(data)) # 输出:
2. json.load():文件读取解析
直接从文件中读取JSON内容并解析:
# 假设存在data.json文件,内容为上述json_str
with open('data.json', 'r', encoding='utf-8') as f:
file_data = json.load(f)
print(file_data)
3. json.dumps():Python对象转JSON字符串
将Python对象序列化为JSON字符串:
python_dict = {"city": "Beijing", "population": 2171}
json_output = json.dumps(python_dict)
print(json_output) # 输出: {"city": "Beijing", "population": 2171}
4. json.dump():写入JSON文件
将Python对象直接写入文件:
new_data = {"language": "Python", "version": 3.9}
with open('output.json', 'w', encoding='utf-8') as f:
json.dump(new_data, f, indent=4) # indent参数控制缩进
生成的output.json内容:
{
"language": "Python",
"version": 3.9
}
三、高级功能与参数详解
1. 处理复杂数据类型
默认情况下,`json`模块仅支持基本数据类型。若需处理日期、自定义类等,需通过`default`参数指定转换函数:
from datetime import datetime
import json
def datetime_handler(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
event = {"time": datetime.now(), "name": "Meeting"}
json_str = json.dumps(event, default=datetime_handler)
print(json_str) # 输出: {"time": "2023-05-20T14:30:00.123456", "name": "Meeting"}
2. 自定义编码/解码(object_hook)
使用`object_hook`将JSON中的特定字段转换为Python自定义类:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def person_decoder(obj):
if '__type__' in obj and obj['__type__'] == 'Person':
return Person(obj['name'], obj['age'])
return obj
json_str = '{"__type__": "Person", "name": "Bob", "age": 30}'
person = json.loads(json_str, object_hook=person_decoder)
print(person.name) # 输出: Bob
3. 控制输出格式
`dumps()`和`dump()`的常用参数:
-
indent
:缩进空格数,美化输出 -
sort_keys
:是否按键名排序 -
ensure_ascii
:是否转义非ASCII字符(设为False保留中文)
data = {"城市": "上海", "人口": 2487}
pretty_json = json.dumps(data, indent=2, ensure_ascii=False)
print(pretty_json)
# 输出:
# {
# "城市": "上海",
# "人口": 2487
# }
四、常见问题与解决方案
1. 处理Unicode字符
默认情况下,`json.dumps()`会将非ASCII字符转义为Unicode编码。若需保留原始字符,设置`ensure_ascii=False`:
chinese_data = {"message": "你好,世界"}
print(json.dumps(chinese_data)) # 输出: {"message": "\u4f60\u597d\uff0c\u4e16\u754c"}
print(json.dumps(chinese_data, ensure_ascii=False)) # 输出: {"message": "你好,世界"}
2. 解析错误处理
当JSON格式无效时,会抛出`json.JSONDecodeError`。可通过`try-except`捕获异常:
invalid_json = '{"name": "Alice", "age": }' # 缺少数字
try:
data = json.loads(invalid_json)
except json.JSONDecodeError as e:
print(f"解析错误: {e.msg} (位置: {e.pos})")
# 输出: 解析错误: Expecting value (位置: 22)
3. 大文件分块解析
对于超大JSON文件,可使用`ijson`库实现流式解析:
import ijson
def parse_large_json(file_path):
with open(file_path, 'r') as f:
for item in ijson.items(f, 'items.item'): # 假设文件结构为{"items": [...]}
print(item)
# 示例文件large.json内容: {"items": [{"id": 1}, {"id": 2}]}
parse_large_json('large.json')
五、性能优化建议
1. 重复解析时复用`json.JSONDecoder`对象
decoder = json.JSONDecoder()
json_str = '{"a": 1, "b": 2}'
data1 = decoder.decode(json_str)
data2 = decoder.decode(json_str) # 复用解析器
2. 使用`orjson`库提升速度(需安装`pip install orjson`)
import orjson
data = {"key": "value"}
fast_json = orjson.dumps(data).decode('utf-8') # 比json模块快3-5倍
六、实际应用场景
1. API数据交互
解析REST API返回的JSON响应:
import requests
import json
response = requests.get('https://api.example.com/data')
if response.status_code == 200:
api_data = json.loads(response.text)
print(api_data['results'][0]['title'])
2. 配置文件管理
使用JSON作为配置文件格式:
# config.json
{
"database": {
"host": "localhost",
"port": 5432
},
"debug": true
}
# 读取配置
with open('config.json') as f:
config = json.load(f)
print(config['database']['host'])
3. 日志数据分析
解析结构化日志中的JSON字段:
log_entry = '{"timestamp": 1684567890, "level": "ERROR", "message": "Disk full"}'
log_data = json.loads(log_entry)
if log_data['level'] == 'ERROR':
send_alert(log_data['message'])
关键词:Python、JSON解析、json模块、序列化、反序列化、数据交换、JSONDecodeError、性能优化、orjson、流式解析
简介:本文全面介绍了Python中JSON数据的解析方法,涵盖json模块的核心函数(loads/load/dumps/dump)、复杂类型处理、格式控制、错误处理及性能优化技巧,结合API交互、配置管理等实际场景,帮助开发者高效处理JSON数据。