json.load() 和 json.loads()辨析

在 Python 的 json 模块中,json.load()json.loads() 都是用于解析 JSON 数据的方法,但它们的输入源和使用场景有本质区别。以下是两者的详细对比:

核心区别总结

输入类型

文件对象

(如

open()

返回的对象)

字符串

(str 或 bytes)

方法名含义

load

=

load from file

loads

=

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. 参数对比

两者的参数基本一致,但输入源不同:

共有参数

cls

自定义 JSON 解码器

object_hook

自定义字典转换逻辑

parse_*

控制数字解析方式(如

parse_int

,

parse_float

特有参数

  • 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. 最佳实践

  1. 优先使用 json.load():
  2. 仅在需要时使用 json.loads():
  3. 避免混淆用法:

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)

通过理解这两个方法的区别,可以:

  1. 更高效地处理不同来源的 JSON 数据
  2. 避免常见的类型错误
  3. 优化内存使用和性能
  4. 编写更健壮的 JSON 解析代码
进阶高级测试工程师 文章被收录于专栏

《高级软件测试工程师》专栏旨在为测试领域的从业者提供深入的知识和实践指导,帮助大家从基础的测试技能迈向高级测试专家的行列。 在本专栏中,主要涵盖的内容: 1. 如何设计和实施高效的测试策略; 2. 掌握自动化测试、性能测试和安全测试的核心技术; 3. 深入理解测试驱动开发(TDD)和行为驱动开发(BDD)的实践方法; 4. 测试团队的管理和协作能力。 ——For.Heart

全部评论

相关推荐

昨天 22:24
已编辑
西安工业大学 C++
点赞 评论 收藏
分享
韵不凡:软件开发的工作需要博士吗?
点赞 评论 收藏
分享
04-17 18:32
门头沟学院 Java
野猪不是猪🐗:他跟你一个学校,你要是进来之后待遇比他好,他受得了?
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客企业服务