当前位置: 首页 > article >正文

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

在当今数字化时代,网络编程无处不在,数据的高效传输与交互是其核心。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 jsondata = {"name": "Alice","age": 30,"hobbies": ["reading", "traveling"]
}
json_str = json.dumps(data)
print(json_str) 
  • json.dump():将 Python 对象序列化后写入到文件对象中。使用时需先打开文件,并指定合适的编码(通常为utf - 8),操作完成后文件会自动关闭(若使用with语句)。
import jsondata = [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 jsonjson_str = '{"name": "Bob", "age": 25, "is_student": false}'
data = json.loads(json_str)
print(data) 
  • json.load():从文件对象中读取 JSON 数据并反序列化为 Python 对象。同样,使用with语句打开文件,确保文件操作的安全性和规范性。
import jsonwith open('data.json', 'r', encoding='utf - 8') as f:data = json.load(f)print(data)

格式化输出

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

  • indent参数:指定缩进的空格数,使 JSON 字符串按层级结构缩进显示。
import jsondata = {"person": {"name": "Charlie","details": {"age": 35,"city": "New York"}}
}
formatted_json = json.dumps(data, indent=4)
print(formatted_json)
  • separators参数:用于指定 JSON 字符串中项与项、键与值之间的分隔符。默认分隔符是, : ,可根据需求调整。
import jsondata = {"key1": "value1", "key2": "value2"}
custom_separators_json = json.dumps(data, separators=(',', ':'))
print(custom_separators_json) 

处理特殊数据类型

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

  • 日期时间类型:先将日期时间对象转换为字符串,再进行 JSON 序列化。
import json
from datetime import datetimenow = 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 jsonclass Point:def __init__(self, x, y):self.x = xself.y = yclass 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 dctpoint = 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 jsondata = {'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,  # 这里使用自定义编码器,可不设置 defaultsort_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.nanelif s == 'Infinity':return math.infelif 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] = valuereturn 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函数的详细使用方法,包含各个形参的介绍和使用示例等。

相关文章:

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

在当今数字化时代,网络编程无处不在,数据的高效传输与交互是其核心。JSON 作为一种轻量级的数据交换格式,凭借其简洁、易读、跨语言的特性,成为网络编程中数据传输与存储的关键技术。无论是前后端数据交互,还是不同系统…...

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

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

查看引脚电平

在Linux系统中,通过cat命令查看/sys/class/gpio/export文件并不能直接获取GPIO引脚的高低电平。/sys/class/gpio/export文件用于向系统请求导出(即启用)某个特定的GPIO引脚,而不是用于读取引脚的状态。 1.导出GPIO引脚&#xff1…...

回归预测 | 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…...

nvidia-smi执行失败,报错-实战生产

目录 报错日志 解决办法 步骤 1: 检查当前安装的 NVIDIA 驱动版本 步骤 2: 检查 NVIDIA 内核模块是否已加载 步骤 3: 重新安装 NVIDIA 驱动程序 使用 apt 重新安装驱动程序 或者使用 dkms 重新生成内核模块 步骤 4: 确认内核版本和驱动兼容性 步骤 5: 更新 initramfs …...

大脑神经网络与机器神经网络的区别

大脑神经网络(生物神经网络)与机器神经网络(人工神经网络,ANN)虽然名称相似,但在结构、功能、学习机制等方面存在显著差异。以下是两者的主要区别: 1. 基础结构与组成 大脑神经网络: 由 生物神经元(约860亿个)通过突触连接形成动态网络。 神经元通过电化学信号(动作…...

firewall-cmd --zone=public --list-ports 已经添加端口了但是仍无法访问

当您使用 firewall-cmd 命令在 Linux 系统中配置防火墙规则时,确保端口可以被访问通常涉及几个步骤。即使您已经使用 firewall-cmd 添加了端口,但仍可能遇到无法访问的问题。以下是一些解决步骤,帮助您确认和解决端口无法访问的问题&#xff…...

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

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

DevOps 进化论:腾讯云 CODING-TM 如何助力企业敏捷转型?

在当今数字化竞争激烈的时代,企业的软件开发模式正经历从传统开发向敏捷开发、DevOps 转型的深刻变革。如何在保证代码质量的同时,加快开发、测试与交付流程,成为众多企业研发团队面临的核心挑战。腾讯云 CODING-TM 作为一站式 DevOps 平台&a…...

前端骨架怎样实现

前端骨架屏(Skeleton Screen)是一种优化页面加载体验的技术,通常在内容加载时展示一个简易的占位符,避免用户看到空白页面。骨架屏通过展示页面结构的骨架样式,让用户有页面正在加载的感觉,而不是等待内容加…...

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

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

[NOIP2007 普及组] 奖学金 题解

(一)读懂题目 关键句:期末,每个学生都有3门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,…...

[创业之路-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 宛如推动这一浪潮前进的双引擎。…...

非标准纸张Word文件无损转换为A4标准纸张的完整教程

在日常办公中,常会遇到需要将非标准纸张大小的Word文档(如A3、B5等)调整为A4标准尺寸的需求。直接修改Word页面设置可能导致排版错乱,而通过 Adobe Acrobat 的印前检查功能可实现内容格式无损缩放。以下是详细操作流程: 一、Word转PDF:保留原始布局 保存为PDF格式 在Word…...

Xlua中C#引用Lua变量,导致Lua侧的GC无法回收的原因及解决方法

1. 引用关系导致: 在 XLua 中,当 C# 端引用了 Lua 变量时,Lua 的垃圾回收器(GC)不会回收这些被引用的变量。这是因为 Lua 的 GC 机制是基于引用计数和标记 - 清除算法的。当 C# 端持有对 Lua 变量的引用时,…...

38.日常算法

1.最短无序连续子数组 题目来源 给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。请你找出符合题意的 最短 子数组,并输出它的长度。 示例 1: 输入…...

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…...

树和二叉树_13

树和二叉树_13 一、HZOJ-245二、题解1.引库2.代码 一、HZOJ-245 货仓选址 ​ 在一条数轴上有 N 家商店,他们的坐标分别为 A[1]−A[N]。现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。为了提高效率,求…...

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

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

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

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

qt的QMainWindow保存窗口和恢复窗口状态

保存窗口状态 QSettings settings("MyCompany", "MyApp"); // 指定存储的应用信息 settings.setValue("mainWindowState", saveState());saveState() 返回一个 QByteArray,包含 所有停靠窗口和工具栏的状态。QSettings 用于存储数据…...

Linux下使用poll函数编写UDP客户端、服务器程序

一、UDP服务器与客户端的区别 对于UDP服务器与客户端,两者都可以通过sendto和recvfrom函数收发数据,它们的主要区别是: 1.服务器一般是等待并响应来自客户端的请求,客户端则是主动发送请求并且等待服务器的响应。 2.服务器端要…...

算法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设计四、结果展示总结 前言 在当今社会,眼科疾病尤其是白内障对人们的视力健康构成了严重威胁。白…...