
Python的JSON模块提供了强大而灵活的工具集,开发人员能够高效处理JSON数据交换。掌握JSON处理不仅是Web开发的基础,更是数据工程的核心技能,合理选择工具和方法,能够使数据交换过程高效而可靠。
JSON(JavaScript Object Notation)作为一种轻量级数据交换格式,凭借其简洁的层次结构和语言无关性,已成为现代应用程序数据交换的标准。Python通过内置的JSON模块提供了强大的JSON处理能力,使开发者能够轻松实现Python对象与JSON格式之间的双向转换。
在JSON与Python之间的数据类型转换存在明确的对应关系:
JSON类型 | Python类型 | Python转JSON类型 |
|---|---|---|
object | dict | dict → object |
array | list | list/tuple → array |
string | str | str → string |
number (int) | int | int/float → number |
number (real) | float | True → true |
true | True | False → false |
false | False | None → null |
null | None |
这种映射关系使得Python的字典和列表可以无缝转换为JSON对象和数组,反之亦然。
要成功解析JSON数据,必须确保其符合严格的格式规范:
# 无效JSON示例(键未用双引号,尾部逗号)
invalid_json = "{'name': 'Alice', 'age': 25,}"
# 有效JSON示例
valid_json = "{\"name\": \"Alice\", \"age\": 25}"json.loads()(load string的缩写)是将JSON格式字符串转换为Python对象的核心方法。此方法适用于处理来自网络API响应或内存中的JSON数据。
import json
# JSON格式字符串
json_str = '{"name": "Alice", "age": 30, "is_student": false}'
# 解析为Python字典
python_dict = json.loads(json_str)
print(type(python_dict)) # <class 'dict'>
print(python_dict["name"]) # Alice当处理包含JSON数组的字符串时,json.loads()会返回Python列表:
json_array_str = '[{"name": "Alice"}, {"name": "Bob"}]'
python_list = json.loads(json_array_str)
print(type(python_list)) # <class 'list'>
print(python_list[0]["name"]) # Alice对于存储在文件中的JSON数据,json.load()方法提供了高效的文件读取与解析能力。此方法会自动处理文件打开和关闭,推荐使用上下文管理器(with语句)确保资源安全释放。
import json
# 从文件读取并解析JSON
with open('data.json', 'r', encoding='utf-8') as f:
data = json.load(f)
print(data["age"]) # 30JSON解析过程中可能遇到多种异常情况,健壮的错误处理至关重要:
try:
data = json.loads(invalid_json)
except json.JSONDecodeError as e:
print(f"JSON解析错误: {e.msg}")
print(f"错误位置: 行{e.lineno}, 列{e.colno}")json.dumps()(dump string的缩写)是将Python对象序列化为JSON字符串的主要方法。通过调整参数,可以控制输出的格式和内容。
data = {
"name": "Alice",
"age": 30,
"is_student": False,
"courses": ["Math", "Physics"]
}
# 基本转换
json_str = json.dumps(data)
print(json_str)
# {"name": "Alice", "age": 30, "is_student": false, "courses": ["Math", "Physics"]}
# 美化输出(缩进和键排序)
pretty_json = json.dumps(data, indent=4, sort_keys=True)
print(pretty_json)
# {
# "age": 30,
# "courses": [
# "Math",
# "Physics"
# ],
# "is_student": false,
# "name": "Alice"
# }
# 处理非ASCII字符
data = {"name": "张三", "city": "北京"}
json_str = json.dumps(data, ensure_ascii=False)
print(json_str) # {"name": "张三", "city": "北京"}当需要将JSON数据持久化存储时,json.dump()方法提供了直接写入文件的便捷方式:
data = {"name": "Alice", "age": 30, "city": "New York"}
with open('person.json', 'w', encoding='utf-8') as f:
json.dump(data, f, indent=4, ensure_ascii=False)当需要序列化非标准JSON类型(如datetime对象)时,可以通过自定义编码器或default函数实现:
from datetime import datetime
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
data = {"event": "Conference", "time": datetime.now()}
json_str = json.dumps(data, cls=CustomEncoder)
print(json_str) # {"event": "Conference", "time": "2025-06-26T14:30:00.123456"}对于单个对象的自定义序列化,可以使用default参数:
def custom_serializer(obj):
if isinstance(obj, datetime):
return obj.strftime("%Y-%m-%d %H:%M:%S")
raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
json_str = json.dumps(data, default=custom_serializer)Pandas库提供了强大的pd.read_json()函数,可将JSON数据直接转换为DataFrame,支持多种数据布局格式。
import pandas as pd
from io import StringIO
# 从JSON字符串创建DataFrame
json_data = '{"name": ["Alice", "Bob"], "age": [25, 30]}'
df = pd.read_json(StringIO(json_data))
print(df)
# name age
# 0 Alice 25
# 1 Bob 30
# 从JSON文件创建DataFrame
df_file = pd.read_json('data.json')使用to_json()方法可将DataFrame转换为JSON格式,通过orient参数控制输出结构:
df = pd.DataFrame({
'value': range(3),
'time': pd.date_range('2025-01-01', periods=3),
'flag': ['A', 'B', 'C']
})
# 不同orient参数示例
print(df.to_json(orient='records'))
# [{"value":0,"time":1735689600000,"flag":"A"},{"value":1,"time":1735776000000,"flag":"B"},{"value":2,"time":1735862400000,"flag":"C"}]
print(df.to_json(orient='split'))
# {"columns":["value","time","flag"],"index":[0,1,2],"data":[[0,1735689600000,"A"],[1,1735776000000,"B"],[2,1735862400000,"C"]]}
print(df.to_json(orient='index'))
# {"0":{"value":0,"time":1735689600000,"flag":"A"},"1":{"value":1,"time":1735776000000,"flag":"B"},"2":{"value":2,"time":1735862400000,"flag":"C"}}当DataFrame中包含时间日期类型时,转换JSON需特别注意:
# 错误方式:时间被转为时间戳
df.to_json('data.json', orient='records')
# 正确方式:先转换为字符串
df['time'] = df['time'].astype(str)
df.to_json('data.json', orient='records', indent=4)输出结果将保持原始时间格式:
[
{
"value": 0,
"time": "2025-01-01 00:00:00",
"flag": "A"
},
{
"value": 1,
"time": "2025-01-02 00:00:00",
"flag": "B"
}
]JSON标准不支持NaN、Infinity等特殊浮点值,但Python的JSON模块可以处理:
data = {"temperature": float('nan'), "distance": float('inf')}
json_str = json.dumps(data, allow_nan=True) # 默认允许对于超大型JSON文件,使用标准JSON模块可能导致内存问题,可考虑以下解决方案:
import ijson
with open('large_file.json', 'rb') as f:
for prefix, event, value in ijson.parse(f):
# 流式处理每个JSON元素
print(f"prefix: {prefix}, event: {event}, value: {value}")在需要处理大量JSON数据的场景,性能优化至关重要:
# 生成紧凑JSON,减少传输大小
compact_json = json.dumps(data, separators=(',', ':'))通过object_hook参数实现JSON到Python对象的映射:
class Person:
def __init__(self, d):
self.__dict__ = d
json_str = '{"name": "Alice", "age": 30}'
person = json.loads(json_str, object_hook=lambda d: Person(d))
print(person.name) # Alice反向转换时,通过default参数指定转换函数:
def person_to_dict(obj):
if isinstance(obj, Person):
return {'name': obj.name, 'age': obj.age}
raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
json_str = json.dumps(person, default=person_to_dict)“无他,惟手熟尔”!有需要的用起来。
如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!
本文分享自 Nicholas与Pypi 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!