百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

Python内置json模块:编码器和解码器详解

liuian 2025-09-04 11:53 4 浏览

知识图谱

1. JSON简介

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript的一个子集,但JSON是完全独立于语言的文本格式。

1.1 JSON的特点

  • 轻量级:JSON的数据格式简洁,相比于XML等数据格式,JSON更加轻量。
  • 易读性:JSON的数据格式清晰,易于人阅读和理解。
  • 易解析:JSON的数据格式简单,易于机器解析和生成。
  • 语言无关:JSON是完全独立于语言的文本格式,几乎所有编程语言都支持JSON。

1.2 JSON的应用场景

  • 数据交换:JSON常用于Web应用中的数据交换,如前后端数据交互。
  • 配置文件:JSON也常用于配置文件,如Node.js中的配置文件。
  • API接口:JSON是RESTful API中最常用的数据格式。

2. Python中的json模块

Python的json模块提供了将Python对象编码为JSON格式的字符串,以及将JSON格式的字符串解码为Python对象的功能。

2.1 json模块的主要功能

  • 编码:将Python对象转换为JSON格式的字符串。
  • 解码:将JSON格式的字符串转换为Python对象。

2.2 json模块的常用函数

2.2.1 json.dumps()

功能:将Python对象编码为JSON格式的字符串。

原型

json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

参数

  • obj:要序列化的Python对象。
  • skipkeys:如果为True,则跳过非基本类型的键。
  • ensure_ascii:如果为True,则输出保证对所有输入的非ASCII字符进行转义。
  • check_circular:如果为False,则跳过容器类型的循环引用检查。
  • allow_nan:如果为False,则对超范围的float值进行序列化将导致ValueError。
  • cls:自定义JSON编码器类。
  • indent:缩进级别,用于美化输出。
  • separators:分隔符元组,用于控制输出格式。
  • default:当对象无法被序列化时调用的函数。
  • sort_keys:如果为True,则字典输出将按键排序。

返回值:JSON格式的字符串。

示例

import json

data = {'name': 'Alice', 'age': 25, 'city': 'New York'}
json_str = json.dumps(data, indent=4)
print(json_str)

2.2.2 json.dump()

功能:将Python对象序列化为JSON格式的字符串,并写入文件。

原型

json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

参数

  • obj:要序列化的Python对象。
  • fp:文件型对象,用于写入JSON数据。
  • 其他参数与json.dumps()相同。

返回值:无。

示例

import json

data = {'name': 'Alice', 'age': 25, 'city': 'New York'}
with open('data.json', 'w') as f:
    json.dump(data, f, indent=4)

2.2.3 json.loads()

功能:将JSON格式的字符串解码为Python对象。

原型

json.loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

参数

  • s:包含JSON数据的字符串。
  • cls:自定义JSON解码器类。
  • object_hook:当解码JSON对象时调用的函数。
  • parse_float:当解码JSON浮点数时调用的函数。
  • parse_int:当解码JSON整数时调用的函数。
  • parse_constant:当解码JSON常量时调用的函数。
  • object_pairs_hook:当解码JSON对象字面值时调用的函数。
  • 其他参数与json.load()相同。

返回值:Python对象。

示例

import json

json_str = '{"name": "Alice", "age": 25, "city": "New York"}'
data = json.loads(json_str)
print(data)

2.2.4 json.load()

功能:将JSON格式的字符串从文件中读取并解码为Python对象。

原型

json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

参数

  • fp:包含JSON数据的文件型对象。
  • 其他参数与json.loads()相同。

返回值:Python对象。

示例

import json

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

3. JSON编码器和解码器

3.1 json.JSONEncoder

功能:用于Python数据结构的可扩展JSON编码器。

原型

class json.JSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)

参数

  • skipkeys:如果为False,则当尝试对非基本类型的键进行编码时将会引发TypeError。
  • ensure_ascii:如果为True,则输出保证将所有输入的非ASCII字符转义。
  • check_circular:如果为True,则列表、字典和自定义的已编码对象将在编码期间进行循环引用检查。
  • allow_nan:如果为True,则编码NaN、Infinity和-Infinity。
  • sort_keys:如果为True,则字典的输出是按照键排序。
  • indent:如果是一个非负整数或者字符串,那么JSON数组元素和对象成员会被美化输出为该值指定的缩进等级。
  • separators:如果指定,应该是一个(item_separator, key_separator)元组。
  • default:如果指定,其应该是一个函数,每当某个对象无法被序列化时它会被调用。

方法

  • default(o):在子类中实现这种方法使其返回o的可序列化对象,或者调用基础实现(引发TypeError)。
  • encode(o):返回Python o数据结构的JSON字符串表达方式。
  • iterencode(o):编码给定对象o,并且让每个可用的字符串表达方式。

示例

import json

class ComplexEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, complex):
            return {'__complex__': True, 'real': obj.real, 'imag': obj.imag}
        return super().default(obj)

data = 1 + 2j
json_str = json.dumps(data, cls=ComplexEncoder)
print(json_str)

3.2 json.JSONDecoder

功能:简单的JSON解码器。

原型

class json.JSONDecoder(*, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None)

参数

  • object_hook:当解码JSON对象时调用的函数。
  • parse_float:当解码JSON浮点数时调用的函数。
  • parse_int:当解码JSON整数时调用的函数。
  • parse_constant:当解码JSON常量时调用的函数。
  • strict:如果为False,则控制字符将被允许在字符串内。
  • object_pairs_hook:当解码JSON对象字面值时调用的函数。

方法

  • decode(s):返回s的Python表示形式。
  • raw_decode(s):从s中解码出JSON文档,并返回一个Python表示形式为2元组以及指明该文档在s中结束位置的序号。

示例

import json

def as_complex(dct):
    if '__complex__' in dct:
        return complex(dct['real'], dct['imag'])
    return dct

json_str = '{"__complex__": true, "real": 1, "imag": 2}'
data = json.loads(json_str, object_hook=as_complex)
print(data)

4. 异常处理

4.1 json.JSONDecodeError

功能:拥有以下附加属性的ValueError的子类。

属性

  • msg:未格式化的错误消息。
  • doc:正在解析的JSON文档。
  • pos:解析失败的开始索引。
  • lineno:对应于pos的行。
  • colno:对应于pos的列。

示例

import json

try:
    json.loads('{"name": "Alice", "age": 25, "city": "New York"')
except json.JSONDecodeError as e:
    print(f"JSON解码错误: {e.msg}")
    print(f"错误位置: {e.pos}")
    print(f"错误行: {e.lineno}")
    print(f"错误列: {e.colno}")

5. 应用案例

5.1 案例1:配置文件读取与写入示例

场景:使用JSON格式存储配置文件,并在程序中读取和写入配置。

代码

import json

# 配置文件路径
config_file = 'config.json'

# 默认配置
default_config = {
    'host': 'localhost',
    'port': 8080,
    'debug': True
}

# 读取配置文件
def read_config():
    try:
        with open(config_file, 'r') as f:
            return json.load(f)
    except FileNotFoundError:
        return default_config

# 写入配置文件
def write_config(config):
    with open(config_file, 'w') as f:
        json.dump(config, f, indent=4)

# 示例
config = read_config()
print("当前配置:", config)

# 修改配置
config['port'] = 9090
write_config(config)
print("更新后的配置已写入文件")

5.2 案例2:复杂对象的JSON序列化示例

场景:将包含复杂对象(如自定义类实例)的数据结构序列化为JSON字符串。

代码

import json

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

class PersonEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Person):
            return {'name': obj.name, 'age': obj.age}
        return super().default(obj)

# 创建Person实例
person = Person('Alice', 25)

# 序列化为JSON字符串
json_str = json.dumps(person, cls=PersonEncoder, indent=4)
print(json_str)

# 反序列化
def person_decoder(dct):
    if 'name' in dct and 'age' in dct:
        return Person(dct['name'], dct['age'])
    return dct

person_data = json.loads(json_str, object_hook=person_decoder)
print(f"反序列化后的Person对象: name={person_data.name}, age={person_data.age}")

6. 学习结

6.1 学习路线

  1. 了解JSON的基本概念和应用场景
  2. 掌握Python中json模块的基本用法,包括json.dumps()json.dump()json.loads()json.load()
  3. 学习JSON编码器和解码器的使用,包括json.JSONEncoderjson.JSONDecoder
  4. 掌握异常处理,特别是json.JSONDecodeError的使用。
  5. 通过实际案例,如配置文件读取与写入、复杂对象的JSON序列化等,巩固所学知识。

6.2 学习总结

通过本教程,我们详细介绍了Python内置模块json的使用方法,包括JSON的基本概念、json模块的主要功能、JSON编码器和解码器的使用、异常处理以及实际应用案例。希望本教程能帮助你更好地理解和使用Python中的JSON处理功能。


持续更新Python编程学习日志与技巧,敬请关注!

相关推荐

C语言学习从内存堆栈视角,给这段枚举代码做个 "内存透视"

从内存堆栈视角,给这段枚举代码做个"内存透视"#include<stdio.h>enumDAY{MON=1,TUE,WED,THU,FR...

Python基础:枚举,都有哪些特点和使用场景呢?

在Python编程语言中,枚举(Enumeration)是一种特殊的类,用于为一组常量创建一个名称空间。枚举类在Python3.4中被引入,提供了一种更加直观和方便的方式来处理一组相关的常量。枚举类...

Java枚举你真的会用吗_java枚举怎么使用

概述Java中枚举,大家在项目中经常使用吧,主要用来定义一些固定值,在一个有限的集合内,比如在表示一周的某一天,一年中的四季等。那你了解枚举的本质吗?了解枚举的一些常见用法吗?枚举介绍和使用枚举主要用...

反射、枚举以及Lambda表达式_反射getmethod

一、反射1.定义Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法(即使是私有的);对于任意一个对象,都能够调用它的任意方法和属性,那么,我们就...

一个高效使用cursor开发项目的方法,怎么让 AI 写的代码不跑题?

最近又用cursor做了一个小应用,番茄时钟,用来管理自己的时间,提高效率。然后使用cursor开发的过程中。有了一些新的感悟。找到了一条可以让Curosr不跑题的办法。生成一份详细的项目资...

前端铜九铁十面试必备八股文——工程化

常用的git命令gitclone:克隆远程仓库到本地。gitinit:在当前目录初始化一个新的Git仓库。gitadd:将文件添加到暂存区,准备提交。gitcommit-m"co...

IntelliJ IDEA 2025.2 的主要更新亮点

以下是该版本的一些关键改进与功能更新:AI增强体验离线Java代码补全:AI助手现在支持在离线模式下进行Java代码块建议,并允许用户选择本地代码模型使用。AIAssistant新增...

一行命令,AI 直接写代码!OpenAI 正式发布 Codex CLI

【一句话速读】OpenAI把2021年的Codex品牌复活,推出全新CodexCLI——一个本地运行的轻量级编码代理。只需npmi-g@openai/codex,它就能在终端里帮...

如何使用高级TypeScript模式构建可扩展的QA框架

TypeScript自动化QA(7部分系列)TypeScript第一步:自动化QA实用路线图如何在TypeScript中使用数组和对象构建强大的QA自动化脚本如何掌握TypeScript基础...

Bun JS工具包新增MySQL驱动和密钥管理功能

Bun团队发布了其JavaScript打包器和运行时的1.2.21版本,该工具使用Zig语言编写,新增了包括MySQL和SQLite内置驱动、YAML解析器以及用于工具和本地开发的密钥管理器等功能。新...

编码 10000 个小时后,开发者悟了:“不要急于发布!”

【CSDN编者按】在软件开发的道路上,时间是最好的老师。根据“一万小时定律”,要成为某个领域的专家,通常需要大约一万小时的刻意练习。本文作者身为一名程序员,也经历了一万小时的编程,最终悟出了一个道理...

一文说明,TypeScript 的装饰器_typescript logo

●装饰器(Decorators)●注意:装饰器目前是一项实验性特性,在未来的版本中可能会发生改变●装饰器一般使用在以下几个地方○类○类属性○类方法○类方法的参数○通过这些我们也能看得出来,...

前端小哥哥:如何使用typescript开发实战项目?

前言笔者上一篇文章:主要写了typescript的用法和核心知识点总结,这篇文章将通过一个实际的前端案例来教大家如何在项目中使用typescript.你将收获如何使用umi快速搭建一个基于React...

一篇文章搞懂TypeScript_typescript implements

TypeScript是JavaScript的超集,一方面给动态类型的js增加了类型校验,另一方面扩展了js的各种功能。原始数据类型字符串数值布尔nullundefinedSymbolBi...

TypeScript的any和unknown,用错一个就是线上Bug

在TypeScript开发中,类型系统是我们抵御运行时错误的第一道防线。但两个特殊类型——any和unknown,却常常被误用,成为线上故障的隐形推手。本文通过真实案例解析,告诉你为什么unknown...