目录
一、引言
介绍JSON的重要性以及它在现代编程和网络通信中的普遍应用,特别是在API和Web服务中。
二、JSON简介
2.1 基本规则:
- 数据在名称/值对中: 数据由键值对构成。键用双引号
"
包裹,后面跟一个冒号:
,然后是值。 - 数据由逗号分隔: 多个键值对由逗号
,
分隔。 - 花括号保存对象: 由花括号
{}
包围的是对象,表示一组无序的键值对。 - 方括号保存数组: 由方括号
[]
包围的是数组,表示值的有序集合。 - 字符串必须用双引号表示: JSON中的字符串必须由双引号
"
包围。 - 数字不用引号: 数值不必使用引号包围。
- 文件以UTF-8编码: JSON文本应该以UTF-8编码保存。
2.2 写法示例:
对象:
{
"name": "John Doe",
"age": 30,
"isStudent": false,
"address": {
"street": "123 Main St",
"city": "Anytown"
}
}
数组
[
"apple",
"banana",
"cherry"
]
数值
{
"integer": 25,
"float": 3.14159
}
字符串
{
"greeting": "Hello, World!"
}
布尔值和null:
{
"isStudent": false,
"nickname": null
}
三、Python中的JSON
3.1 序列化和反序列:
- 序列化(Serialization)是将对象转换为字节流的过程,以便可以在网络上传输或保存到磁盘或数据库中。在序列化过程中,对象的状态和数据将被转换为二进制格式,使其能够被传输或存储。
- 反序列化(Deserialization)则是将序列化的字节流重新转换回对象的过程。通过反序列化,我们可以从字节流中重新构建出原始对象,并且恢复其状态和数据。
3.2 Python json
模块概览
基本功能:
3.3 读取JSON数据
- 如何使用
json.loads()
从字符串中读取JSON数据
import json
json_data = '{"name": "John", "age": 30, "city": "New York"}'
python_obj = json.loads(json_data)
print(python_obj["name"]) # 输出: John
- 使用
json.load()
从文件中读取JSON数据
import json
with open('data.json', 'r', encoding='utf-8') as file:
python_obj = json.load(file)
print(python_obj["age"]) # 输出: 30
3.4 写入JSON数据
- 使用
json.dumps()
将Python对象转换为JSON字符串
import json
python_dict = {"name": "Jane", "age": 25, "city": "Paris"}
json_data = json.dumps(python_dict)
print(json_data) # 输出: {"name": "Jane", "age": 25, "city": "Paris"}
- 使用
json.dump()
将Python对象写入文件
import json
python_dict = {"name": "Jane", "age": 25, "city": "Paris"}
with open('data.json', 'w', encoding='utf-8') as file:
json.dump(python_dict, file)
3.5 JSON进阶处理
3.5.1 美化输出(pretty-printing)
要美化JSON输出,你可以使用json.dumps()
方法的indent
参数。此外,sort_keys
参数可以让JSON数据中的键按字母顺序输出。
import json
data = {
"name": "John Doe",
"age": 30,
"isStudent": False,
"courses": ["Math", "Science"]
}
pretty_json = json.dumps(data, indent=4, sort_keys=True)
print(pretty_json)
3.5.2 处理复杂数据类型(日期、自定义对象等)
JSON标准本身不支持特定的复杂数据类型(如日期或自定义对象)。要处理这些类型,你需要在序列化和反序列化过程中进行自定义转换。
日期
对于日期类型,你可以在序列化时将其转换为字符串,在反序列化时再从字符串转换回日期类型。
import json
from datetime import datetime, date
def date_handler(obj):
if hasattr(obj, 'isoformat'):
return obj.isoformat()
else:
raise TypeError("Type is not serializable")
data = {
"name": "John Doe",
"birthday": date(1990, 4, 28)
}
json_data = json.dumps(data, default=date_handler)
print(json_data)
自定义对象
对于自定义对象,可以定义一个函数,将对象转换为可JSON序列化的形式。同样,也可以在反序列化时进行相应的转换。
class User:
def __init__(self, name, age):
self.name = name
self.age = age
# 自定义序列化函数
def encode_user(obj):
if isinstance(obj, User):
return {'name': obj.name, 'age': obj.age} # 或其他可识别的格式
raise TypeError("Object of type User is not JSON serializable")
user = User("Jane Doe", 32)
user_json = json.dumps(user, default=encode_user)
print(user_json)
3.5.3 解决编码问题
在处理非ASCII字符时,设置ensure_ascii
参数为False
可以避免将这些字符转换成ASCII字符编码的序列,从而可以直接在JSON字符串中使用原始字符。
data = {
"name": "张三",
"age": 30,
"isStudent": False
}
json_data = json.dumps(data, ensure_ascii=False)
print(json_data)
3.6 JSON与异常处理
- 处理JSON解析错误
import json
json_data = '{"name": "John", age: 30, "city": "New York"}' # 错误的JSON格式
try:
python_obj = json.loads(json_data)
except json.JSONDecodeError as e:
print(f"解析JSON时发生错误:{e}")