当前位置: 首页 > 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 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.kler.cn/a/547074.html

相关文章:

  • 智能体或是GPT、Deepseek等大模型的发展方向
  • 深度学习与增强现实的完美邂逅:开启未来智能交互的新篇章
  • unity删除了安卓打包平台,unityhub 还显示已经安装,怎么解决
  • lightning.pytorch.callbacks内置的Callbacks介绍
  • LeapMotion第2代 Unity示范代码(桌面开发)
  • DeepSeekApi对接流式输出异步聊天功能:基于Spring Boot和OkHttp的SSE应用实现
  • 1.5 企业级AI大模型四阶技术全景解析:从Prompt到Pre-training的进化路径
  • 23. AI-大语言模型
  • 【AI系列】从零开始学习大模型GPT (2)- Build a Large Language Model (From Scratch)
  • Springboot整合ES
  • Linux系统使用ollama本地安装部署DeepSeekR1 + open-webui
  • 字玩FontPlayer开发笔记14 Vue3实现多边形工具
  • wps接入DeepSeek教程
  • uniapp语音时的动态音波的实现
  • SpringBoot中Mybatis记录执行sql日志
  • 基于 STM32 平台的音频特征提取与歌曲风格智能识别系统
  • TypeScript装饰器 ------- 学习笔记分享
  • DeepSeek 模型部署与使用技术评测(基于阿里云零门槛解决方案)
  • 部署onlyoffice后,php版的callback及小魔改(logo和关于)
  • Java项目引入DeepSeek搭建私有AI