> 技术文档 > Python 标准库详解:Json 模块的使用_python json

Python 标准库详解:Json 模块的使用_python json


一、模块简介

        json库是Python内置的一个标准库,用于在Python对象和JSON数据之间进行序列化和反序列化,json库在日常的开发中经常用到,它广泛应用于接口开发、配置管理、数据交换等场景。
        由于日常开发中会经常用到这个库,今天闲来无事,打算来总结一下一些常用的json库的一些方法以及参数的含义。
        本文会结合代码以及运行结果的方式来帮助你理解并真的会用他!

二、Json库的使用

 首先,json库是python内置的一个库,我们直接调用即可

import json

接下来,我们一起来看看json将Python对象进行序列化的两种方法

(后续标题会使用这种方法,可以简要了解一下*args和**kwargs,如下注)

注:在 Python 中,*args 和**kwargs 用于函数定义中接收可变数量的参数。*args表示接收任意数量的位置参数,函数内部将其打包为一个元组;而**kwargs 则用于接收任意数量的关键字参数,函数内部将其打包为一个字典。它们常用于不确定传入参数数量的场景,能够提高函数的灵活性与通用性。例如:def func(*args, **kwargs):就可以同时接收多个普通参数和命名参数。

2.1 序列化

2.1 json.dump(*args, **kwargs)方法

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)

Python 对象 编码成 JSON 格式,并 写入到类文件对象 fp

其中各个参数的详解如下

参数 含义 默认值 obj 要序列化的 Python 对象(如 dictlist 等) — fp 类文件对象,必须支持 .write() 方法,如打开的文件句柄 — skipkeys 如果为 True,则字典中非字符串键会被跳过,否则会报 TypeError False ensure_ascii 如果为 True,所有非 ASCII 字符会转义为 \\uXXXX,否则输出原字符 True check_circular 如果为 False,允许循环引用,否则报 ValueError True allow_nan 如果为 True,允许 NaN, Infinity, -Infinity 并序列化为对应标识符,否则报 ValueError True cls 自定义的 JSONEncoder 子类,用于扩展序列化行为 None indent 缩进空格数;若为 None 则输出紧凑版;若为非负整数,则美化输出 None separators (item_sep, key_sep) 元组,定义项与项、键与值间分隔符;默认 (\',\', \': \') None default 可调用,遇到不可序列化对象时回调,将其转为可序列化类型 None sort_keys 如果为 True,字典的键会被排序后输出 False

        其中很常用的应该是obj,fp,ensure_ascii(想输出中文,一般会置为False),indent(调整输出缩进,可以使json格式更美观),sort_keys(用作排序)。

以下是一个简单的调用示例,将 Python 对象写入到 JSON 文件中。

import json# 创建一个字典对象data = { \'名字\': \'my\', \'年龄\': 20, \'tags\': [\'python\', \'博客\']}# 将字典写入到 data.json 文件中with open(\'out.json\', \'w\', encoding=\'utf-8\') as f: json.dump( data, f, ensure_ascii=False, # 保留中文 indent=2,  # 缩进 2 格 sort_keys=True # 字段按字母排序 )

运行过后会生成一个out.json文件,内容如下

        想要深刻的理解这些常用的参数,不妨我们试试修改他们,如果ensure_ascii置为True会是什么样子,非ASCii字符就会转为\\uXXXX,如下图所示

当我不适用缩进,也就是将indent置为0,会怎么样呢?

        就会变成这样,是不是没有有缩进的看着舒服呢?当不按字段排序也就是sort_keys置为False时,会是什么样子呢?

由这些可以知道,很好的利用这些参数,可以让可读性很强,观感更舒服。

总结:

  • Python 对象写入到 JSON 文件
  • 适合将数据保存为 JSON 格式的配置文件、缓存数据等
  • indent以及sort_keys参数让文件内容更可读,常用于调试或用户可读场景

2.2 json.dumps(*args, **kwargs)方法

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) → str

Python 对象编码为 JSON 格式的 字符串

参数说明:和json.dump()几乎完全一致,区别是返回一个字符串,而不是写入文件。

以下是一个简单的调用示例,将 Python 对象转换成 JSON 字符串。

import json# 同样的 Python 对象data = { \'名字\': \'my\', \'年龄\': 20, \'tags\': [\'python\', \'博客\']}# 将 Python 对象转为 JSON 字符串json_str = json.dumps(data, ensure_ascii=False, indent=2)# 打印 JSON 字符串print(json_str)

打印内容如下

 总结:

  • Python 对象转换成 JSON 字符串
  • dumps() 的结果是一个字符串,常用于传输数据(如发送给接口、保存数据库)
  • dump() 相比,区别是是否“写入文件”

 2.2 反序列化

2.2.1 json.load(*args, **kwargs)方法

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

从类文件对象 fp读取 JSON 数据,并转换为 Python 对象

 其中各个参数的详解如下

参数名 类型 说明 fp 文件对象 打开并读取的 JSON 文件对象 cls type 自定义的 JSONDecoder 子类 object_hook function 将 JSON 对象(dict)转换为其他类型的函数 parse_float function 自定义将 JSON 浮点数转换为其他类型(如 Decimal) parse_int function 自定义将 JSON 整数转换为其他类型(如 float) parse_constant function 自定义解析常量 NaNInfinityobject_pairs_hook function 代替 object_hook,保留键值顺序(如 OrderedDict)

 一般只需用到fp参数,其他参数可根据自己的需求来使用。

以下是一个简单的调用示例,从 JSON 文件中读取数据为 Python 对象。

import json# 假设已经存在out.json文件,并且文件内容是:# data = {# \'名字\': \'my\', # \'年龄\': 20, # \'tags\': [\'python\', \'博客\']# }# 从文件读取并转换为 Python 对象with open(\'out.json\', \'r\', encoding=\'utf-8\') as f: loaded_data = json.load(f)# 打印读取到的 Python 对象print(loaded_data)

 打印内容如下

 总结

  • 从 JSON 文件中读取数据为 Python 对象

  • 常用于读取配置、存储的数据文件

  • 注意文件路径、编码要匹配

 2.2.2 json.loads(*args, **kwargs)方法

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

将 JSON 格式的 字符串 反序列化为 Python 对象

参数说明:与load()相同,但第一个参数是字符串 。

 以下是一个简单的调用示例,将 JSON 字符串解析成 Python 对象。

import json# 一个合法的 JSON 字符串json_str = \'{\"名字\": \"my\", \"年龄\": 20, \"tags\": [\"python\", \"博客\"]}\'# 转换为 Python 字典data = json.loads(json_str)# 访问其中的数据print(data[\'名字\']) # 输出:myprint(data[\'年龄\']) # 输出:20print(data[\'tags\']) # 输出:博客

打印内容如下

总结

  • 将 JSON 字符串解析成 Python 对象
  • JSON 中的 truefalsenull 会自动映射为 Python 的 TrueFalseNone

2.3 总结对比 

分类 函数名 作 用 数据来源 数据目标 常用参数 ✅ 序列化 json.dump() 将 Python 对象写入到 JSON 文件 中 Python 对象 文件(.jsonfp, indent, ensure_ascii, default, sort_keys ✅ 序列化 json.dumps() 将 Python 对象转换为 JSON 字符串 Python 对象 字符串(str) indent, ensure_ascii, default, sort_keys 🔄 反序列化 json.load()JSON 文件中读取内容为 Python 对象 文件(.json) Python 对象(dict等) fp, object_hook, parse_float, parse_int 🔄 反序列化 json.loads()JSON 字符串 转换为 Python 对象 字符串(str) Python 对象(dict等) object_hook, parse_float, parse_int

三、进阶用法:default 与 object_hook

3.1 default 参数 —— 定制化序列化(Python ➜ JSON)

        当我们在使用json.dump()或json.dumps()将 Python 对象转换为 JSON 时,如果对象中包含 JSON 标准不支持的类型(如datetime、自定义类对象等),就会抛出错误。这时就可以通过default参数,告诉 JSON 如何处理这些类型

json.dumps(obj, default=custom_function)

参数说明:

  • obj:要序列化的 Python 对象
  • default:一个函数,接收一个不能序列化的对象,返回一个可被序列化的类型(如:字符串、数字、列表、字典)

 以下是一个简单示例,序列化一个datetime对象。

import jsonfrom datetime import datetime# 原始数据data = { \"event\": \"我的第一篇博客发表时间\", \"time\": datetime(2025, 6, 8, 15, 0)}# 自定义转换函数def datetime_serializer(obj): if isinstance(obj, datetime): return obj.isoformat() # 转为标准字符串 raise TypeError(f\"无法序列化类型: {type(obj)}\")# 使用 default 序列化json_str = json.dumps(data, default=datetime_serializer, ensure_ascii=False, indent=2)print(json_str)

打印内容如下

如果不进行该定制化序列化,该datetime就是JSON标准所不支持的类型,而提供了default的参数,会告诉JSON如何处理这些数据(也就是所定义的datetime_seriallizer函数)则会报错,而定制化序列化很好的解决了这个问题。下面我们来一个进阶例子。

以下是一个示例,序列化自定义类对象。

class Student: def __init__(self, name, score): self.name = name self.score = scorestudent = Student(\"小z\", 100)def student_serializer(obj): if isinstance(obj, Student): return {\"name\": obj.name, \"score\": obj.score} raise TypeError(\"无法序列化的对象\")json_str = json.dumps(student, default=student_serializer, ensure_ascii=False)print(json_str)

打印内容如下

 总结:

        default参数用于解决 无法被 JSON 默认序列化的对象(如自定义类、datetime等),它接收一个函数,将特殊对象转换为可被 JSON 接受的标准格式(如字典或字符串)。常用于json.dumps()和json.dump()中。

3.2 object_hook 参数:定制化反序列化(JSON ➜ Python 对象)

        当我们在使用json.load()或json.loads()将 JSON 字符串转为 Python 对象时,默认只返回 dict 类型。但我们可以通过object_hook参数,自定义将 JSON 字典转换为 Python 中的类实例,实现“还原成对象”。

json.loads(json_str, object_hook=custom_decoder)

参数说明:

  • 待解析的 JSON 字符串
  • 一个函数,它会接收反序列化后的每一个 JSON 对象(即字典dict),并返回转换后的 Python 对象
    (它会在 JSON 嵌套结构中从最内层到外层递归调用)

 以下是一个进阶示例,将 JSON 反序列化为自定义类

class Student: def __init__(self, name, score): self.name = name self.score = score# JSON 字符串json_str = \'{\"name\": \"小z\", \"score\": 100}\'# 自定义解码函数def dict_to_student(d): return Student(d[\'name\'], d[\'score\'])# 使用 object_hook 解码student = json.loads(json_str, object_hook=dict_to_student)print(student.name) # 小zprint(student.score) # 100

打印内容如下

        经过我们前面的学习,我们知道json.loads()会将json格式的数据反序列化为python对象,而我们所加的这个参数object_hook=dict_to_student,就等价于一个映射函数,将经典的python对象映射为我们所自定义的类对象。方便我们可以直接调用自定义类的功能。

下面我们来一个进阶例子,将带类型字段的 JSON 动态还原多个对象类型。

class Student: def __init__(self, name, score): self.name = name self.score = scoreclass Teacher: def __init__(self, name, subject): self.name = name self.subject = subjectjson_str = \'\'\'[ {\"type\": \"student\", \"name\": \"小z\", \"score\": 100}, {\"type\": \"teacher\", \"name\": \"小l\", \"subject\": \"数学\"}]\'\'\'def smart_decoder(d): if d.get(\"type\") == \"student\": return Student(d[\"name\"], d[\"score\"]) elif d.get(\"type\") == \"teacher\": return Teacher(d[\"name\"], d[\"subject\"]) return d # 默认返回 dictdata = json.loads(json_str, object_hook=smart_decoder)for obj in data: print(type(obj), vars(obj)) # 输出对象类型和属性字典

打印内容如下

这里只是在前者的例子上多加了一个自定义类,在映射函数中多加了一个判断逻辑。 

3.3 总结对比

参数名 用于方法 用途 输入数据类型 输出数据类型 default dumps() / dump() 自定义不可序列化对象的转换 非 JSON 类型对象(如类) 可序列化对象(如字典、字符串) object_hook loads() / load() 自定义 JSON 字典的解析 JSON 对象(dict) Python 对象(如类实例)

 比较常见的场景和建议

场景 建议用法
  • 序列化 datetime、自定义类
default 参数 还原为类对象 用 object_hook 参数 多类型自动识别 结合 type 字段与 object_hook 实现 嵌套结构还原 object_hook 会自动递归调用

四、注意事项

  • Python JSON dict object list, tuple array str string int, float number True/False true/false None null
  • dumps() 与 loads() 用于字符串处理,dump() 与 load() 用于文件处理
  • 不支持直接序列化自定义类、函数、集合等 —— 需借助 default 参数手动转换

 五、结语

        相信今天所讲的这些在你的json生涯中已经绰绰有余了,json模块完结撒花!!!        

        这是我写博客的第二篇,也是第二天,想着每天抽出来一点闲暇时间来写一些东西,顺便也丰富一下自己的逻辑表达能力,以及知识储备能力,后续会陆续推出其他各种模块包的经典用法,等有闲时间了,当下时间有点紧,其他方面的东西在当下不适合写,等今年过了,明年开始尝试写一些项目实战还有原理性的东西!