《Python 中 JSON 的魔法秘籍:从入门到精通的进阶指南》

news2025/2/19 9:43:37

在当今数字化时代,网络编程无处不在,数据的高效传输与交互是其核心。JSON 作为一种轻量级的数据交换格式,凭借其简洁、易读、跨语言的特性,成为网络编程中数据传输与存储的关键技术。无论是前后端数据交互,还是不同系统间的信息共享,JSON 都扮演着重要角色。Python 作为广泛应用于网络编程的编程语言,熟练掌握 JSON 在 Python 中的使用方法,是开发者实现高效数据处理与交互的必备技能,能够显著提升网络应用的性能和稳定性。

JSON简介

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,在 Python 中,json模块提供了处理 JSON 数据的功能,使得 Python 程序可以方便地对数据进行序列化(将 Python 数据类型转换为 JSON 格式的字符串)和反序列化(将 JSON 格式的字符串转换回 Python 数据类型)。以下是 JSON 在 Python 中的详细使用方法:

序列化(编码)

  • json.dumps():将 Python 对象转换为 JSON 格式的字符串。支持的 Python 对象类型有字典、列表、元组、字符串、数字、布尔值和None,转换规则为:字典转换为 JSON 对象,列表和元组转换为 JSON 数组,字符串、数字、布尔值和None保持原有格式。
import json

data = {
    "name": "Alice",
    "age": 30,
    "hobbies": ["reading", "traveling"]
}
json_str = json.dumps(data)
print(json_str) 
  • json.dump():将 Python 对象序列化后写入到文件对象中。使用时需先打开文件,并指定合适的编码(通常为utf - 8),操作完成后文件会自动关闭(若使用with语句)。
import json

data = [1, 2, 3, 4]
with open('data.json', 'w', encoding='utf - 8') as f:
    json.dump(data, f)

反序列化(解码)

  • json.loads():将 JSON 格式的字符串转换为 Python 对象。转换后的 Python 对象类型与原 JSON 数据结构对应,如 JSON 对象转换为 Python 字典,JSON 数组转换为 Python 列表。
import json

json_str = '{"name": "Bob", "age": 25, "is_student": false}'
data = json.loads(json_str)
print(data) 
  • json.load():从文件对象中读取 JSON 数据并反序列化为 Python 对象。同样,使用with语句打开文件,确保文件操作的安全性和规范性。
import json

with open('data.json', 'r', encoding='utf - 8') as f:
    data = json.load(f)
    print(data)

格式化输出

在使用json.dumps()时,可通过参数对输出的 JSON 字符串进行格式化,提高可读性。

  • indent参数:指定缩进的空格数,使 JSON 字符串按层级结构缩进显示。
import json

data = {
    "person": {
        "name": "Charlie",
        "details": {
            "age": 35,
            "city": "New York"
        }
    }
}
formatted_json = json.dumps(data, indent=4)
print(formatted_json)
  • separators参数:用于指定 JSON 字符串中项与项、键与值之间的分隔符。默认分隔符是, : ,可根据需求调整。
import json

data = {"key1": "value1", "key2": "value2"}
custom_separators_json = json.dumps(data, separators=(',', ':'))
print(custom_separators_json) 

处理特殊数据类型

JSON 本身不支持所有 Python 数据类型,如日期时间、自定义类的实例等。处理这些特殊数据类型时,需要额外操作。

  • 日期时间类型:先将日期时间对象转换为字符串,再进行 JSON 序列化。
import json
from datetime import datetime

now = datetime.now()
now_str = now.strftime('%Y-%m-%d %H:%M:%S')
data = {"time": now_str}
json_data = json.dumps(data)
print(json_data) 
  • 自定义类的实例:通过继承json.JSONEncoder类,并重写default()方法,指定自定义类实例的序列化方式;反序列化时,利用object_hook参数传入自定义函数解析 JSON 数据为自定义类实例。
import json


class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y


class PointEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, Point):
            return {'x': o.x, 'y': o.y}
        return super().default(o)


def point_decoder(dct):
    if 'x' in dct and 'y' in dct:
        return Point(dct['x'], dct['y'])
    return dct


point = Point(1, 2)
json_str = json.dumps(point, cls=PointEncoder)
loaded_point = json.loads(json_str, object_hook=point_decoder)
print(loaded_point.x, loaded_point.y) 

 json.dumps函数详解

函数定义

json.dumps 函数用于将 Python 对象编码成 JSON 格式的字符串,其参数及用途如下:

参数名含义类型默认值
obj要转换为 JSON 字符串的 Python 对象,如字典、列表等可序列化的 Python 对象

*这个表示在这个 仅限关键字 标记 * 之后的形参都必须以关键字参数形式传递该形参,不能是位置形参!仅限关键字参数*
skipkeys若为 True,当字典键不是基本类型(strintfloatboolNone)时跳过该键;为 False 时遇非基本类型键会抛 TypeError 异常布尔值False
ensure_ascii为 True 时,非 ASCII 字符转义为 \uXXXX 形式;为 False 时,非 ASCII 字符原样输出布尔值True
check_circular为 True 时检查对象是否有循环引用,有则抛 ValueError 异常;为 False 不检查,可能导致无限递归布尔值True
allow_nan为 True 时允许在 JSON 中使用 NaNInfinity 和 -Infinity;为 False 遇这些值抛 ValueError 异常布尔值True
cls自定义的 JSON 编码器类,用于处理特殊对象的序列化None
indent指定缩进的整数或字符串,使生成的 JSON 更易读。整数表示空格数,字符串(如 '\t')则用该字符串缩进整数或字符串None
separators元组 (item_separator, key_separator),指定 JSON 字符串中元素和键值对的分隔符元组(', ', ': ')
default处理无法直接序列化对象的函数,遇无法序列化对象时调用此函数函数None
sort_keys为 True 时,生成的 JSON 字符串中键按字典序排序布尔值False
**kw

**kw 是关键字参数,用于接收任意数量的额外关键字参数,它本质上是一个字典

它允许函数调用时接收显式定义外的关键字参数,并传递给自定义编码器类。在函数内,可通过 kw 字典访问这些参数,如调用 dumps 时传入 **{'a': 1, 'b': 2},就能用 kw['a'] 和 kw['b'] 获取值。

 

**kw 可扩展函数功能,开发者按需传入额外参数实现特殊处理,无需修改原参数列表;也能促进函数交互,在复杂程序中传递通用参数,增强代码灵活性与可维护性。

**kw相关使用示例

import json

data = {'name': 'Alice', 'age': 30}
json_str = json.dumps(data, ensure_ascii=False, my_custom_param='value') 
# 这里的my_custom_param就是通过**kw传递的额外参数
print(json_str)

在上述示例中,my_custom_param 就是通过 **kw 传递的额外参数。虽然在标准的 json.dumps() 函数中,并没有定义 my_custom_param 这个参数,但通过 **kw 可以接收并在函数内部进行相应的处理。不过在标准库的 json.dumps() 函数中,并不会对自定义的 my_custom_param 做任何处理,只是将其作为 kw 字典的一个键值对保存下来。如果是自定义的 dumps 函数,可以在函数内部对 kw 中的参数进行相应的逻辑处理。

json.dumps完整使用示例

import json
from datetime import datetime

# 自定义编码器处理日期对象
class CustomJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        return super().default(obj)

# 定义一个包含多种类型数据的 Python 对象
data = {
    'name': '张三',
    'age': 25,
    'is_student': True,
    'grades': [90, 85, 92],
    'birth_date': datetime(1999, 10, 15),
    ('tuple_key',): '特殊键值'  # 非基本类型键
}

# 使用 json.dumps 函数进行转换
try:
    json_str = json.dumps(
        data,
        skipkeys=True,  # 跳过非基本类型的键
        ensure_ascii=False,  # 不转义非 ASCII 字符
        check_circular=True,  # 检查循环引用
        allow_nan=True,  # 允许 NaN 等特殊值
        cls=CustomJSONEncoder,  # 使用自定义编码器
        indent=4,  # 缩进 4 个空格
        separators=(',', ':'),  # 设置分隔符
        default=None,  # 这里使用自定义编码器,可不设置 default
        sort_keys=True  # 按键排序
    )
    print(json_str)
except (TypeError, ValueError) as e:
    print(f"转换出错: {e}")

代码解释

  1. 自定义编码器 CustomJSONEncoder:继承自 json.JSONEncoder,重写 default 方法,处理 datetime 对象的序列化。
  2. 定义数据对象 data:包含字符串、整数、布尔值、列表、日期对象和非基本类型键。
  3. 调用 json.dumps 函数:设置多个参数进行转换,包括跳过非基本类型键、不转义非 ASCII 字符、使用自定义编码器等。
  4. 异常处理:捕获可能的 TypeError 和 ValueError 异常并输出错误信息。

json.loads详解

json.loads函数定义:

json.loads 函数用于将 JSON 格式的字符串解析为 Python 对象,以下是其各个形参的详细介绍:

形参类型描述默认值
sstr必需参数,包含 JSON 数据的字符串,loads 函数会将其解析为对应的 Python 对象。
*这个表示在这个 仅限关键字 标记 * 之后的形参都必须以关键字参数形式传递该形参,不能是位置形参!仅限关键字参数*
clsclass自定义的 JSON 解码器类。若提供该类,会使用此类进行 JSON 数据的解码操作。None
object_hookcallable当解析到 JSON 对象(字典)时调用的函数。此函数接收一个字典作为参数,并返回一个 Python 对象,可用于对解析后的字典进行自定义处理。None
parse_floatcallable用于解析 JSON 中浮点数的函数。解析到浮点数时会调用该函数,它接收一个字符串参数,并返回一个 Python 浮点数对象,可自定义浮点数的解析方式。None
parse_intcallable用于解析 JSON 中整数的函数。解析到整数时会调用该函数,它接收一个字符串参数,并返回一个 Python 整数对象,可自定义整数的解析方式。None
parse_constantcallable用于解析 JSON 中常量(如 NaNInfinity-Infinity)的函数。解析到这些常量时会调用该函数,它接收常量对应的字符串作为参数,并返回一个 Python 对象。None
object_pairs_hookcallable当解析到 JSON 对象(字典)时调用的函数,与 object_hook 不同的是,它接收一个由键值对元组组成的列表作为参数,常用于处理键重复的情况或需要保留键值对顺序的场景。None
**kw可变关键字参数接收其他额外的关键字参数,可传递给自定义的解码器类。 同json.dumps函数

json.loads 完整使用示例

import json
import math

# 自定义解码器类
class CustomDecoder(json.JSONDecoder):
    def decode(self, s):
        result = super().decode(s)
        if isinstance(result, dict):
            for key, value in result.items():
                if isinstance(value, str):
                    result[key] = value.upper()
        return result

# 自定义对象钩子函数
def custom_object_hook(dct):
    if 'name' in dct:
        dct['greeting'] = f"HELLO, {dct['name']}!"
    return dct

# 自定义浮点数解析函数
def custom_parse_float(s):
    return float(s) * 2

# 自定义常量解析函数
def custom_parse_constant(s):
    if s == 'NaN':
        return math.nan
    elif s == 'Infinity':
        return math.inf
    elif s == '-Infinity':
        return -math.inf

# 自定义对象对钩子函数
def custom_object_pairs_hook(pairs):
    result = {}
    for key, value in pairs:
        if key in result:
            result[key] = [result[key], value]
        else:
            result[key] = value
    return result

# 包含 JSON 数据的字符串
json_str = '{"name": "John", "price": 9.99, "value": NaN, "name": "Doe"}'

# 使用 json.loads 进行解析
python_obj = json.loads(
    json_str,
    cls=CustomDecoder,
    object_hook=custom_object_hook,
    parse_float=custom_parse_float,
    parse_constant=custom_parse_constant,
    object_pairs_hook=custom_object_pairs_hook
)

print(python_obj)

代码解释

  1. 自定义解码器类 CustomDecoder:对解析后的字典中的字符串值进行大写转换。
  2. 自定义对象钩子函数 custom_object_hook:当解析结果包含 name 键时,添加一个 greeting 键。
  3. 自定义浮点数解析函数 custom_parse_float:将解析到的浮点数乘以 2。
  4. 自定义常量解析函数 custom_parse_constant:处理 NaNInfinity 和 -Infinity 常量。
  5. 自定义对象对钩子函数 custom_object_pairs_hook:处理键重复的情况,将重复键的值合并为列表。
  6. 调用 json.loads:传入自定义的解码器类和各个钩子函数,对 JSON 字符串进行解析。

总结: 文章围绕 JSON 在 Python 中的使用展开。先是介绍了 JSON 的概念,以及在 Python 中json模块处理 JSON 数据的关键作用。接着从序列化和反序列化入手,讲解json.dumps()json.dump()json.loads()json.load()等函数的使用,还提及利用indentseparators参数对 JSON 字符串格式化输出。还针对 JSON 不支持的日期时间、自定义类实例等特殊数据类型,给出了相应的处理办法。  最后还从python源码的角度详细分析了json.dumps函数和json.loads函数的详细使用方法,包含各个形参的介绍和使用示例等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2297801.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【漫话机器学习系列】091.置信区间(Confidence Intervals)

置信区间(Confidence Intervals)详解 1. 引言 在统计学和数据分析中,我们通常希望通过样本数据来估计总体参数。然而,由于抽样的随机性,我们不可能得到精确的总体参数,而只能通过估计值(如均值…

回归预测 | Matlab实现PSO-HKELM粒子群算法优化混合核极限学习机多变量回归预测

回归预测 | Matlab实现PSO-HKELM粒子群算法优化混合核极限学习机多变量回归预测 目录 回归预测 | Matlab实现PSO-HKELM粒子群算法优化混合核极限学习机多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.回归预测 | Matlab实现PSO-HKELM粒子群算法优化混合核…

QTreeView添加网格线

一.效果 二.实现 网格线虽然可以用样式表添加,但效果不好。这里重写QTreeView的drawRow函数来实现网格线的绘制。 void QHTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {QTreeView::drawRow(painter…

Golang的多团队协作编程模式与实践经验

Golang的多团队协作编程模式与实践经验 一、多团队协作编程模式概述 在软件开发领域,多团队协作编程是一种常见的工作模式。特别是对于大型项目来说,不同团队间需要协同合作,共同完成复杂的任务。Golang作为一种高效、并发性强的编程语言&…

AI前端开发的学习成本与回报——效率革命的曙光

近年来,人工智能技术飞速发展,深刻地改变着各行各业。在软件开发领域,AI写代码工具的出现更是掀起了一场效率革命。AI前端开发,作为人工智能技术与前端开发技术的完美结合,正展现出巨大的发展潜力,为开发者…

[创业之路-297]:经济周期与股市、行业的关系

目录 一、经济周期的种类 1、短周期(基钦周期) 2、中周期(朱格拉周期) 3、长周期(康德拉季耶夫周期) 当下处于康波周期的哪个阶段? 4、建筑周期(库涅茨周期) 二、…

Dav_笔记14:优化程序提示 HINTs -3

查询转换的提示 以下每个提示都指示优化程序使用特定的SQL查询转换: ■NO_QUERY_TRANSFORMATION ■USE_CONCAT ■NO_EXPAND ■REWRITE和NO_REWRITE ■MERGE和NO_MERGE ■STAR_TRANSFORMATION和NO_STAR_TRANSFORMATION ■事实和NO_FACT ■UNNEST和NO_UNNEST…

递归乘法算法

文章目录 递归乘法题目链接题目详解解题思路:代码实现: 结语 欢迎大家阅读我的博客,给生活加点impetus!! 让我们进入《题海探骊》,感受算法之美!! 递归乘法 题目链接 在线OJ 题目…

从当下到未来:蓝耘平台和 DeepSeek 应用实践的路径探索,勾勒 AI 未来新蓝图

我的个人主页 我的专栏:人工智能领域,希望能帮助到大家!!!点赞👍收藏❤ 引言:AI 浪潮中的双引擎 在人工智能蓬勃发展的时代,蓝耘平台与 DeepSeek 宛如推动这一浪潮前进的双引擎。…

Leetcode 算法题 9 回文数

起因, 目的: 数学法。 % 求余数, 拆开组合,组合拆开。 这个题,翻来覆去,拆开组合, 组合拆开。构建的过程。 题目来源,9 回文数: https://leetcode.cn/problems/palindrome-number…

docker compose部署flink集群

本次部署2个jobmanager和3个taskmanager 一、部署zookeeper集群 flink使用zookeeper用作高可用 部署集群参考:docker compose部署zookeeper集群-CSDN博客 二、创建目录及配置文件 创建timezone文件,内容填写Asia/Shanghai 手动创建目录&#xff1a…

常用架构图:业务架构、产品架构、系统架构、数据架构、技术架构、应用架构、功能架构及信息架构

文章目录 引言常见的架构图I 业务架构图-案例模块功能说明1. 用户界面层 (UI)2. 应用服务层3. 数据管理层4. 基础设施层业务流程图示例技术实现II 功能架构图 -案例功能模块说明1. 船舶监控模块2. 报警管理模块3. 应急响应模块4. 通信管理模块5. 数据分析模块数据管理层基础设施…

AI前端开发:解放创造力,而非取代它

近年来,人工智能技术飞速发展,深刻地改变着各行各业,前端开发领域也不例外。越来越多的AI写代码工具涌现,为开发者带来了前所未有的效率提升。很多人担心AI会取代程序员的创造力,但事实并非如此。本文将探讨AI辅助前端…

算法17(力扣217)存在重复元素

1、问题 给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。 2、示例 (1) 示例 1: 输入:nums [1,2,3,1] 输出:…

NO.16十六届蓝桥杯备战|for循环|七道习题|ceil|floor|pow(C++)

for循环 for循环语法形式 for 循环是三种循环中使⽤最多的, for 循环的语法形式如下: //形式1 for(表达式1; 表达式2; 表达式3) 语句;//形式2 //如果循环体想包含更多的语句,可以加上⼤括号 for(表达式1; 表达式2; 表达式3) { …

深度学习实战基础案例——卷积神经网络(CNN)基于DenseNet的眼疾检测|第4例

文章目录 前言一、数据准备二、项目实战2.1 设置GPU2.2 数据加载2.3 数据预处理2.4 数据划分2.5 搭建网络模型2.6 构建densenet1212.7 训练模型2.8 结果可视化 三、UI设计四、结果展示总结 前言 在当今社会,眼科疾病尤其是白内障对人们的视力健康构成了严重威胁。白…

(一)Axure制作移动端登录页面

你知道如何利用Axure制作移动端登录页面吗?Axure除了可以制作Web端页面,移动端也是可以的哦,下面我们就一起来看一下Axure制作移动端登录页面的过程吧。 第一步:从元件中拖入一个矩形框,并设置其尺寸为:37…

【Linux】【进程】epoll内核实现

【Linux】【进程】epoll内核实现 1 epoll提供的三个函数 1.1 epoll_create(int size); epoll_create()成功返回内核事件表的文件描述符,失败返回-1size 参数现在并不起作用 1.2 epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); epoll_ctl()成…

ICRA-2025 | 具身导航如何跨越地形障碍?SARO:通过视觉语言模型实现地形穿越

作者:Shaoting Zhu, Derun Li, Linzhan Mou, Yong Liu, Ningyi Xu, Hang Zhao 单位:清华大学交叉信息研究院,上海交通大学电子信息与电气工程学院,浙江大学计算机科学与技术学院,宾夕法尼亚大学GRASP实验室&#xff0…

当 LSTM 遇上 ARIMA!!

大家好,我是小青 ARIMA 和 LSTM 是两种常用于时间序列预测的模型,各有优劣。 ARIMA 擅长捕捉线性关系,而 LSTM 擅长处理非线性和长时间依赖的关系。将ARIMA 和 LSTM 融合,可以充分发挥它们各自的优势,构建更强大的时…