json.load() 和 json.loads()辨析
在 Python 的 json
模块中,json.load()
和 json.loads()
都是用于解析 JSON 数据的方法,但它们的输入源和使用场景有本质区别。以下是两者的详细对比:
核心区别总结
输入类型 | 文件对象 (如
返回的对象) | 字符串 (str 或 bytes) |
方法名含义 |
= load from file |
= load from string |
典型使用场景 | 直接读取 JSON 文件 | 解析字符串或字节流中的 JSON |
是否需要文件操作 | 需要先打开文件 | 无需文件操作 |
性能 | 适合大文件(流式读取) | 适合小数据(需先加载全部内容到内存) |
1. json.load()
:从文件对象解析
使用方式
import json # 从文件读取 with open("data.json", "r", encoding="utf-8") as f: data = json.load(f) # 直接传入文件对象
特点
- 必须传入文件对象(通过
open()
打开) - 自动处理文件编码(需指定正确的
encoding
参数) - 内存高效:流式读取大文件时更优
- 典型场景: 读取本地 JSON 文件处理网络请求返回的 JSON 文件流
2. json.loads()
:从字符串解析
使用方式
import json # 从字符串解析 json_str = '{"name": "Alice", "age": 30}' data = json.loads(json_str) # 直接传入字符串 # 从文件内容解析(需两步) with open("data.json", "r", encoding="utf-8") as f: content = f.read() # 先读取为字符串 data = json.loads(content)
特点
- 输入必须是字符串或字节流(bytes)
- 需自行处理文件读取(先读取全部内容到内存)
- 灵活性强:可处理任何来源的 JSON 字符串
- 典型场景: 解析 API 返回的 JSON 字符串处理内存中的 JSON 数据动态生成的 JSON 内容
3. 参数对比
两者的参数基本一致,但输入源不同:
共有参数
| 自定义 JSON 解码器 |
| 自定义字典转换逻辑 |
| 控制数字解析方式(如
,
) |
特有参数
json.load()
额外支持:json.loads()
额外支持:
4. 错误处理
两者在遇到格式错误的 JSON 时都会抛出 json.JSONDecodeError
,但触发场景不同:
json.load()
的常见错误
# 错误示例:直接传入文件路径(应传入文件对象) data = json.load("data.json") # TypeError: expected file object
json.loads()
的常见错误
# 错误示例:传入非字符串 data = json.loads(123) # TypeError: the JSON object must be str, bytes or bytearray # 格式错误的 JSON 字符串 json_str = "{'name': 'Bob'}" # JSON 必须使用双引号 data = json.loads(json_str) # JSONDecodeError
5. 性能对比
测试代码
import json import timeit # 测试文件大小:1MB JSON 文件 def test_load(): with open("large.json", "r") as f: json.load(f) def test_loads(): with open("large.json", "r") as f: content = f.read() json.loads(content) print("json.load():", timeit.timeit(test_load, number=100)) print("json.loads():", timeit.timeit(test_loads, number=100))
典型结果
json.load(): 0.89 seconds json.loads(): 1.12 seconds
json.load()
更快:因为直接流式解析文件json.loads()
较慢:需要先将整个文件读入内存
6. 最佳实践
- 优先使用 json.load():
- 仅在需要时使用 json.loads():
- 避免混淆用法:
7. 特殊场景处理
处理字节流(如网络二进制数据)
# 从 bytes 解码 json_bytes = b'{"status": "OK"}' data = json.loads(json_bytes.decode("utf-8")) # 先解码为字符串
自定义解码逻辑
# 将 JSON 中的时间字符串转换为 datetime 对象 def decode_datetime(dct): if "timestamp" in dct: dct["timestamp"] = datetime.fromisoformat(dct["timestamp"]) return dct with open("data_with_time.json") as f: data = json.load(f, object_hook=decode_datetime)
通过理解这两个方法的区别,可以:
- 更高效地处理不同来源的 JSON 数据
- 避免常见的类型错误
- 优化内存使用和性能
- 编写更健壮的 JSON 解析代码
进阶高级测试工程师 文章被收录于专栏
《高级软件测试工程师》专栏旨在为测试领域的从业者提供深入的知识和实践指导,帮助大家从基础的测试技能迈向高级测试专家的行列。 在本专栏中,主要涵盖的内容: 1. 如何设计和实施高效的测试策略; 2. 掌握自动化测试、性能测试和安全测试的核心技术; 3. 深入理解测试驱动开发(TDD)和行为驱动开发(BDD)的实践方法; 4. 测试团队的管理和协作能力。 ——For.Heart