2.1 模块 json
JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,易于被人阅读和书写,同时也易于被计算机解析和生成。JSON 常用于服务器和 web 应用之间传递数据,以及存储配置和设置。
模块 json
在 Python 中提供了序列化(将 Python 对象转换为 JSON 字符串)和反序列化(将 JSON 字符串转换为 Python 对象)的功能。这个模块是 Python 标准库的一部分,并且在处理 JSON 数据时被广泛使用。
模块 json
的主要功能与 pickle
的类似,原理相同。标准就是标准嘛!
-
处理字符串:
-
json.dumps(obj)
— 将 Python 对象转换为 JSON 字符串。 -
json.loads(s)
— 将 JSON 字符串转换为 Python 对象。
-
-
处理文件:
-
json.dump(obj, file)
— 将 Python 对象序列化并写入文本文件中。 -
json.load(file)
— 从包含 JSON 格式数据的文本文件中反序列化 Python 对象。
-
让我们通过一些例子来更好地记住这些函数的使用方法。
2.2 序列化为字符串
将 Python 对象序列化为 JSON 字符串
要将对象序列化为字符串,只需把它传给 json.dumps()
函数。
import json
# 用于序列化的对象示例
data = {
"name": "Alice",
"age": 30,
"is_student": False,
"courses": ["Math", "Science"],
"address": {
"city": "New York",
"zip_code": "10001"
}
}
# 将 Python 对象转换为 JSON 字符串
json_string = json.dumps(data, indent=4)
print("序列化数据 (JSON):", json_string)
将 JSON 字符串反序列化为 Python 对象
要从字符串中获取对象,只需将包含对象描述的 JSON 字符串传递给 json.loads()
方法。
import json
# 用于反序列化的 JSON 字符串示例
json_string = '''
{
"name": "Alice",
"age": 30,
"is_student": false,
"courses": ["Math", "Science"],
"address": {
"city": "New York",
"zip_code": "10001"
}
}
'''
# 将 JSON 字符串转换为 Python 对象
data = json.loads(json_string)
print("反序列化数据 (Python):", data)
2.3 序列化到文件
将 Python 对象写入 JSON 文件
要将对象写入文件,需调用 json.dump()
方法。处理文件时重要的是使用异常处理,以正确处理可能的错误。以下是一个例子:
import json
# 用于序列化的对象示例
data = {
"name": "Bob",
"age": 25,
"is_student": True,
"courses": ["History", "Literature"],
"address": {
"city": "Los Angeles",
"zip_code": "90001"
}
}
# 带有异常处理的 Python 对象写入 JSON 文件
try:
with open('data.json', 'w') as file:
json.dump(data, file, indent=4)
print("数据已成功写入文件。")
except IOError:
print("写入文件时出错。")
except json.JSONEncodeError:
print("JSON 编码错误。")
从 JSON 文件中读取 Python 对象
读取也非常简单——只需将文件传递给 json.load()
方法。这里同样重要的是使用异常处理:
import json
# 带有异常处理的从 JSON 文件中读取 Python 对象
try:
with open('data.json', 'r') as file:
data = json.load(file)
print("从文件中反序列化的数据 (Python):", data)
except IOError:
print("读取文件时出错。")
except json.JSONDecodeError:
print("JSON 解码错误。")
2.4 函数的附加参数
在序列化函数中,可以传递附加参数来让你的 JSON 更漂亮:
-
skipkeys
: 若为True
,则跳过那些不是字符串、数字或None
的键。 -
ensure_ascii
: 若为True
,所有非 ASCII 字符将使用 Unicode 转义序列进行转义。 -
indent
: 若指定一个数字,将添加缩进以提高可读性。 -
sort_keys
: 若为True
,则 JSON 中的键将按字母顺序排序。
使用 json.dumps()
参数的示例:
import json
data = {"c": 3, "b": 2, "a": 1}
# 带有键排序和缩进的序列化
json_string = json.dumps(data, indent=4, sort_keys=True)
print(json_string)
2.5 自定义解码器和编码器
模块 json
允许使用自定义函数来对对象进行序列化和反序列化。
自定义编码器的示例
首先,我们创建一个特殊的编码器类,它会检查内部对象的类型
如果对象类型 == datetime,则将对象作为 ISO 格式的字符串返回
。
import json
from datetime import datetime
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
data = {
"name": "Alice",
"timestamp": datetime.now()
}
# 使用自定义编码器进行序列化
json_string = json.dumps(data, cls=CustomEncoder, indent=4)
print(json_string)
自定义解码器的示例
对于反向操作,我们同样需要一个将字符串转换为日期的函数。例如,可以简单地
检查字段名称,如果它叫做 timestamp,则将字符串转换为 datetime 对象
:
import json
from datetime import datetime
def custom_decoder(dct):
if 'timestamp' in dct:
dct['timestamp'] = datetime.fromisoformat(dct['timestamp'])
return dct
json_string = '''
{
"name": "Alice",
"timestamp": "2023-05-15T14:30:00"
}
'''
# 使用自定义解码器进行反序列化
data = json.loads(json_string, object_hook=custom_decoder)
print(data)
GO TO FULL VERSION