eagleye

Python json 模块深度解析:loads() 与 dumps() 全场景指南

 


 

(一)一、模块概述

Python 标准库中的 json 模块提供了 json.loads()JSON 字符串转 Python 对象)和 json.dumps()Python 对象转 JSON 字符串)两个核心函数,是处理 JSON 数据的核心工具。本文将从基础用法到高级场景,全面解析这两个函数的使用技巧。

 


 

(二)二、核心函数详解

1.2.1 json.dumps()Python 对象 → JSON 字符串

功能:将 Python 字典、列表等可序列化对象转换为 JSON 格式字符串。

(1)2.1.1 基础用法示例

import json

# 定义 Python 对象(字典)
data = {
    "name": "张三",
    "age": 30,
    "is_student": False,
    "courses": ["数学", "英语"]
}

# 转换为 JSON 字符串
json_str = json.dumps(data)
print(json_str)
# 输出:{"name": "张三", "age": 30, "is_student": false, "courses": ["数学", "英语"]}

(2)2.1.2 常用参数详解

参数

类型

作用

示例

indent

int/None

控制缩进空格数(美化输出),None 表示无缩进

json.dumps(data, indent=4) → 输出带 4 空格缩进的 JSON

ensure_ascii

bool

是否转义非 ASCII 字符(默认 True),False 保留原字符

json.dumps(data, ensure_ascii=False) → 中文直接显示,不转义为 \u

sort_keys

bool

是否按字典键排序(默认 False)

json.dumps(data, sort_keys=True) → 键按字母顺序排列

separators

tuple

控制键值对和列表项的分隔符(默认 (', ', ': '))

json.dumps(data, separators=(',', ':')) → 紧凑输出(无空格)

default

function

自定义序列化规则(处理默认无法序列化的对象,如日期、自定义类)

见下文「高级用法」示例

(3)2.1.3 高级用法场景

场景1:序列化日期对象
Python 内置的 datetime 对象无法直接序列化,需通过 default 参数定义规则:

from datetime import datetime

def serialize_datetime(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()  # 转换为 ISO 8601 格式(如 "2025-06-18T14:30:00")
    raise TypeError(f"对象 {type(obj)} 无法序列化")

data = {"event": "会议", "time": datetime.now()}
json_str = json.dumps(data, default=serialize_datetime)
# 输出:{"event": "会议", "time": "2025-06-18T14:30:00.123456"}

场景2:紧凑输出(减少体积)
通过 separators 去除冗余空格,适用于网络传输或存储:

# 紧凑模式(无缩进,键值对无空格)
json_str = json.dumps(data, separators=(',', ':'), indent=None)
# 输出:{"name":"张三","age":30,"is_student":false,"courses":["数学","英语"]}

 


 

2.2.2 json.loads()JSON 字符串 → Python 对象

功能:将 JSON 格式字符串解析为 Python 字典、列表等对象。

(1)2.2.1 基础用法示例

json_str = '{"name": "李四", "age": 25, "active": true}'
data = json.loads(json_str)  # 解析为 Python 字典
print(data["name"])  # 输出:李四

(2)2.2.2 常用参数详解

参数

类型

作用

示例

object_hook

function

自定义字典转换规则(将解析后的字典转换为自定义对象)

见下文「高级用法」示例

parse_float

function

自定义浮点数解析(覆盖默认的 float() 转换)

parse_float=lambda x: round(float(x), 2) → 保留两位小数

parse_int

function

自定义整数解析(覆盖默认的 int() 转换)

parse_int=lambda x: int(x, 16) → 解析十六进制字符串为整数

parse_constant

function

处理特殊常量(如 Infinity、NaN、-Infinity)

自定义异常处理,防止恶意输入

(3)2.2.3 高级用法场景

场景1:解析为自定义对象
通过 object_hook  JSON 字典转换为 Python 类实例:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

def dict_to_person(d):
    if "name" in d and "age" in d:
        return Person(d["name"], d["age"])  # 转换为 Person 对象
    return d  # 其他字典保持不变

json_str = '{"name": "王五", "age": 28}'
person = json.loads(json_str, object_hook=dict_to_person)
print(type(person))  # 输出:<class '__main__.Person'>

场景2:自定义数值解析
通过 parse_float  parse_int 调整数值解析规则:

json_str = '{"price": "12.3456", "hex": "0xff"}'

# 解析浮点数时保留两位小数,解析整数时自动检测进制(0x 开头为十六进制)
data = json.loads(
    json_str,
    parse_float=lambda x: round(float(x), 2),  # 12.3456 → 12.35
    parse_int=lambda x: int(x, 0)  # 自动检测进制(0xff → 255)
)
print(data)  # 输出:{'price': 12.35, 'hex': 255}

 


 

(三)三、JSON 与 Python 类型对应关系

JSON 与 Python 的数据类型存在严格的映射规则,需特别注意以下几点:

JSON 类型

Python 类型

说明

object

dict

JSON 对象始终转换为 Python 字典

array

list

JSON 数组始终转换为 Python 列表

string

str

JSON 字符串转换为 Python 字符串

number(int)

int

JSON 整数转换为 Python 整数

number(real)

float

JSON 浮点数转换为 Python 浮点数

true

True

JSON 布尔值 true 转换为 Python True

false

False

JSON 布尔值 false 转换为 Python False

null

None

JSON null 转换为 Python None

 


 

(四)四、异常处理与调试

1.4.1 常见异常类型

  • json.JSONDecodeErrorJSON 字符串格式错误(如缺少引号、括号不匹配)。
  • TypeError:尝试序列化无法被 JSON 支持的对象(如 datetime、自定义类实例)。

2.4.2 异常处理示例

import json
from datetime import datetime

# 示例1:处理 JSON 解析错误
try:
    invalid_json = '{"name": "错误格式", age: 25}'  # 缺少引号的 "age"
    data = json.loads(invalid_json)
except json.JSONDecodeError as e:
    print(f"解析失败:{e.msg}(行 {e.lineno}, 列 {e.colno}")
    # 输出:解析失败:Expecting property name enclosed in double quotes(行 1, 列 12)

# 示例2:处理序列化失败
try:
    data = {"time": datetime.now()}  # datetime 对象无法直接序列化
    json_str = json.dumps(data)
except TypeError as e:
    print(f"序列化失败:{e}")
    # 输出:序列化失败:Object of type datetime is not JSON serializable

 


 

(五)五、性能优化技巧

1.5.1 减少冗余输出

通过 separators  indent=None 生成紧凑的 JSON 字符串,降低传输或存储体积:

# 紧凑模式(无缩进,无空格)
json_str = json.dumps(data, separators=(',', ':'), indent=None)

2.5.2 使用高性能库替代

对于高频或大数据量场景,可使用第三方库 orjson(比标准库快 2-3 倍):

import orjson  # 需通过 pip install orjson 安装

data = {"name": "高效解析", "value": 100}
# 序列化(返回 bytes 类型)
json_bytes = orjson.dumps(data)
# 反序列化
data = orjson.loads(json_bytes)

3.5.3 避免重复解析

对同一 JSON 字符串多次解析时,优先解析一次后复用结果:

# 低效:重复解析
data1 = json.loads(json_str)
data2 = json.loads(json_str)

# 高效:解析一次,重复使用
parsed_data = json.loads(json_str)
data1 = parsed_data
data2 = parsed_data

 


 

(六)六、实际应用场景

1.6.1 配置文件读写

# 读取配置文件
with open("config.json", "r") as f:
    config = json.load(f)  # 等价于 json.loads(f.read())

# 写入配置文件(美化输出)
with open("config.json", "w") as f:
    json.dump(config, f, indent=2)  # 等价于 f.write(json.dumps(config, indent=2))

2.6.2 API 数据处理

通过 requests 库获取 API 数据并解析:

import requests

response = requests.get("https://api.example.com/data")
data = json.loads(response.text)  # 手动解析

# 或直接使用 requests 内置的 json() 方法(等价于 json.loads(response.text))
data = response.json()

3.6.3 自定义类的序列化与反序列化

为自定义类添加 to_json()  from_json() 方法,实现对象的持久化:

class User:
    def __init__(self, name, email):
        self.name = name
        self.email = email

    def to_json(self):
        return json.dumps(self.__dict__)  # 序列化对象属性

    @classmethod
    def from_json(cls, json_str):
        data = json.loads(json_str)
        return cls(**data)  # 反序列化为对象实例

# 使用示例
user = User("张三", "zhangsan@example.com")
json_str = user.to_json()  # 输出:'{"name": "张三", "email": "zhangsan@example.com"}'
new_user = User.from_json(json_str)

 


 

(七)总结

json.loads()  json.dumps()  Python 处理 JSON 数据的核心工具,通过灵活使用参数(如 indent、object_hook)和异常处理,可以覆盖从简单配置到复杂对象的全场景需求。结合性能优化技巧(如使用 orjson),可进一步提升数据处理效率。

posted on 2025-06-18 20:11  GoGrid  阅读(767)  评论(0)    收藏  举报

导航