目录
- [1. json 模块介绍](#1. json 模块介绍)
-
- [1.1 json 模块快用导航](#1.1 json 模块快用导航)
- [1.2 什么是JSON](#1.2 什么是JSON)
-
- [1.2.1 JSON的特点](#1.2.1 JSON的特点)
- [1.2.2 JSON的基本语法](#1.2.2 JSON的基本语法)
- [1.2.3 JSON数据类型](#1.2.3 JSON数据类型)
- [1.2.4 JSON示例](#1.2.4 JSON示例)
- [1.2.5 JSON使用场景](#1.2.5 JSON使用场景)
- [1.2.6 JSON的优缺点](#1.2.6 JSON的优缺点)
- [1.2.7 JSON和XML的比较](#1.2.7 JSON和XML的比较)
- [1.3 json 模块](#1.3 json 模块)
- [2. dump() 方法 --- 转换为 JSON 格式写入文件](#2. dump() 方法 --- 转换为 JSON 格式写入文件)
-
- [2.1 语法参考](#2.1 语法参考)
- [2.2 实例演示](#2.2 实例演示)
-
- [2.2.1 将 JSON 格式字符串写入到文件中](#2.2.1 将 JSON 格式字符串写入到文件中)
- [2.2.2 防止 ASCII 码写到 json 文件中](#2.2.2 防止 ASCII 码写到 json 文件中)
- [2.2.3 将 csv 文件转换为 json 文件](#2.2.3 将 csv 文件转换为 json 文件)
- [2.2.4 修改 json 文件中的数据](#2.2.4 修改 json 文件中的数据)
- [3. dumps() 方法 --- 将 Python 对象转换为 JSON 字符串](#3. dumps() 方法 --- 将 Python 对象转换为 JSON 字符串)
-
- [3.1 语法参考](#3.1 语法参考)
- [3.2 实例演示](#3.2 实例演示)
-
- [3.2.1 Python 对象转换为 JSON 格式的字符串并按照 JSON 格式缩进显示](#3.2.1 Python 对象转换为 JSON 格式的字符串并按照 JSON 格式缩进显示)
- [3.2.2 去掉符号后面的空格](#3.2.2 去掉符号后面的空格)
- [3.2.3 字典类型转换为 JSON 格式字符串](#3.2.3 字典类型转换为 JSON 格式字符串)
- [3.2.4 按照字典排序顺序输出 (a 到 z)](#3.2.4 按照字典排序顺序输出 (a 到 z))
- [3.2.5 将数组转换为 JSON 格式字符串](#3.2.5 将数组转换为 JSON 格式字符串)
- [3.2.6 将列表转换为 JSON 格式字符串](#3.2.6 将列表转换为 JSON 格式字符串)
- [4. load() 方法 --- 从 json 文件中读取数据](#4. load() 方法 --- 从 json 文件中读取数据)
-
- [4.1 语法参考](#4.1 语法参考)
- [4.2 实例演示](#4.2 实例演示)
-
- [4.2.1 从 json 文件中读取数据](#4.2.1 从 json 文件中读取数据)
- [4.2.2 读取文本数据并将其转换为JSON格式( 从TXT文本中解析JSON格式)](#4.2.2 读取文本数据并将其转换为JSON格式( 从TXT文本中解析JSON格式))
- [4.2.3 向原有 json 文件追加数据](#4.2.3 向原有 json 文件追加数据)
- [5. loads() 方法 --- 将 JSON 格式转换成 Python 字典](#5. loads() 方法 --- 将 JSON 格式转换成 Python 字典)
-
- [5.1 语法参考](#5.1 语法参考)
- [5.2 实例演示](#5.2 实例演示)
-
- [5.2.1 简单读取 json 文件中的数据](#5.2.1 简单读取 json 文件中的数据)
- [5.2.2 将 JSON 格式转换为字典](#5.2.2 将 JSON 格式转换为字典)
- [6. JSONDecodeError() 方法 --- 返回解码错误信息](#6. JSONDecodeError() 方法 --- 返回解码错误信息)
-
- [6.1 语法参考](#6.1 语法参考)
- [6.2 实例演示](#6.2 实例演示)
-
- [6.2.1 单双引号使用不当导致 JSONDecodeError 错误](#6.2.1 单双引号使用不当导致 JSONDecodeError 错误)
博主发现当我们自己不知道
Python
某个模块的用法时,自己又没有相关笔记什么的,一般人很少去官网进行查阅,然后在网上乱找一通,描述的也不详细,非常地浪费时间,故博主决定自己将常用模块中常用的方法进行总结,以便后期自己查阅和网上的朋友们查找学习。今天开始总结我们的第二个常用模块:json
模块。
Python 中的 json
模块提供了对 JSON
的支持,用于将 JSON
格式字符串转换为 Python
对象。首先需要了解一下什么是 JSON
。
1. json 模块介绍
1.1 json 模块快用导航
1.2 什么是JSON
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它易于人类阅读和编写,同时也方便机器解析和生成。JSON 是基于 JavaScript 语言的对象表示法,但独立于语言,它已经成为一种常用的标准数据格式,广泛用于 Web 开发、API 数据传输、配置文件等场景。https://www.json.org/json-en.html
1.2.1 JSON的特点
- 轻量级:JSON 格式非常简洁,只有少量的语法符号,适合在网络上传输数据。
- 结构化数据:JSON 可以表示简单的数据结构,如字符串、数字、布尔值、数组、对象等,也可以表示嵌套的复杂数据结构。
- 跨平台:JSON 与编程语言无关,几乎所有的编程语言都提供了处理 JSON 的库或函数,使其广泛使用于多种系统之间的数据交换。
1.2.2 JSON的基本语法
- 对象(Object):表示键值对的集合,用大括号 {} 包裹,键和值之间用冒号
:
分隔,多个键值对之间用逗号 , 分隔。 - 数组(Array):表示一个有序的值列表,用方括号 [] 包裹,多个值之间用逗号 , 分隔。
- 键(Key):必须是字符串类型,并用双引号
""
包裹。 - 值(Value):可以是字符串、数字、布尔值、数组、对象或 null。
1.2.3 JSON数据类型
- 字符串(String):必须用双引号括起来。字符串内部可以包含 Unicode 字符、转义字符(如 \n、\t 等)。
- 数字(Number):可以是整数或浮点数,表示方式与常规数字相同。
- 布尔值(Boolean):两个值,true 或 false,用来表示逻辑状态。
- 数组(Array):有序的数据列表,可以包含任何类型的元素(包括嵌套对象和数组)。
- 对象(Object):无序的键值对集合,键是字符串,值可以是任何类型的数据。
- 空值(null):表示空或无数据。
1.2.4 JSON示例
json
{
"name": "Amo",
"age": 18,
"isStudent": true,
"courses": ["Math", "Computer Science"],
"address": {
"street": "123 Main St",
"city": "New York",
"zipcode": "10001"
},
"phoneNumbers": null
}
这个 JSON 对象描述了一个人的基本信息:
- name:表示字符串
"Amo"
。 - age:表示数字 18。
- isStudent:布尔值,表示是否为学生,值为 true。
- courses:表示数组,包含字符串
"Math"
和"Computer Science"
。 - address:嵌套的对象,包含 street、city 和 zipcode 三个字段。
- phoneNumbers:表示 null,即没有电话号码信息。
1.2.5 JSON使用场景
- 数据传输:JSON 经常用于客户端与服务器之间的数据交换。通过 API 或 AJAX 请求发送和接收 JSON 格式的数据。
- 配置文件:JSON 被用作程序和服务的配置文件格式,易于人类阅读和修改。
- 数据库:某些 NoSQL 数据库(如 MongoDB)直接使用 JSON 或其变体 BSON 作为数据存储格式。
- Web 开发:许多 Web 框架和前端工具(如 React、Vue.js)广泛使用 JSON 处理数据和状态管理。
1.2.6 JSON的优缺点
JSON 的优点:
- 易读性:JSON 语法非常简单,易于人类阅读和编写。
- 轻量化:相较于 XML,JSON 更简洁,占用的存储空间和传输带宽更小。
- 语言无关性:JSON 独立于编程语言,易于与各种编程语言互操作。
- 解析速度快:大多数语言都有高效的 JSON 解析库,能快速转换为相应的数据结构。
JSON 的缺点:
- 缺乏数据类型支持:JSON 只有有限的几种基本数据类型(字符串、数字、布尔值、数组、对象、null),不支持日期、时间、二进制数据等复杂类型。
- 安全性问题:如果不小心将 JSON 数据作为 JavaScript 代码执行,可能导致安全漏洞,如跨站脚本攻击(XSS)。应该始终使用安全的 JSON 解析器。
- 无注释:JSON 不支持注释,因此不适合用作需要大量注释的配置文件格式。
1.2.7 JSON和XML的比较
1.3 json 模块
在 Python 中处理 JSON 可以通过内置的 json 模块来完成。主要有两个功能:序列化(将 Python 对象转换为 JSON 格式字符串)和反序列化(将 JSON 格式字符串转换为 Python 对象)。如下图所示:
2. dump() 方法 --- 转换为 JSON 格式写入文件
2.1 语法参考
dump()
方法用于将 Python 对象转换为 JSON 格式字符串后写入到文件中。语法格式如下:
python
In [21]: json.dump?
Signature:
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,
)
Docstring:
Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
``.write()``-supporting file-like object).
If ``skipkeys`` is true then ``dict`` keys that are not basic types
(``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped
instead of raising a ``TypeError``.
If ``ensure_ascii`` is false, then the strings written to ``fp`` can
contain non-ASCII characters if they appear in strings contained in
``obj``. Otherwise, all such characters are escaped in JSON strings.
If ``check_circular`` is false, then the circular reference check
for container types will be skipped and a circular reference will
result in an ``RecursionError`` (or worse).
If ``allow_nan`` is false, then it will be a ``ValueError`` to
serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
in strict compliance of the JSON specification, instead of using the
JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
If ``indent`` is a non-negative integer, then JSON array elements and
object members will be pretty-printed with that indent level. An indent
level of 0 will only insert newlines. ``None`` is the most compact
representation.
If specified, ``separators`` should be an ``(item_separator, key_separator)``
tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and
``(',', ': ')`` otherwise. To get the most compact JSON representation,
you should specify ``(',', ':')`` to eliminate whitespace.
``default(obj)`` is a function that should return a serializable version
of obj or raise TypeError. The default simply raises TypeError.
If *sort_keys* is true (default: ``False``), then the output of
dictionaries will be sorted by key.
To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
``.default()`` method to serialize additional types), specify it with
the ``cls`` kwarg; otherwise ``JSONEncoder`` is used.
File: f:\dev_tools\python\python310\lib\json\__init__.py
Type: function
参数说明:
(1) obj:表示 Python 对象。
(2) fp:表示一个支持 write() 方法的文件对象。
(3) *:星号本身不是参数。星号表示其后面的参数都是关键字参数,需要使用关键字参数传值,否则程序会出现错误。
(4) skipkeys:默认值为 False。如果值为 True,则不是基本对象 (包括str、int、float、bool、None) 的字典的键会被跳过,否则引发一个 TypeError 错误信息。
(5) ensure_ascii:默认值为 True,会将所有输入的非 ASCII 字符转义输出,如果值为 False,会将输入的非 ASCII 字符原样输出。
(6) check_circular:表示检验循环引用,默认值为 True。如果值为 False,则容器类型的循环引用会被跳过并引发一个 OverflowError 错误。
(7) allow_nan:默认值为 True。如果值为 False,那么在对 JSON 规范以外的 float 类型值 (nan、inf 和 -inf) 进行序列化时将会引发一个 ValueError 错误;如果值为 True,则使用它们的 JavaScript 等价形式(NaN、Infinity 和 -Infinity )。
(8) cls:默认值为 None。通过该关键字参数可以指定自定义的 JSONEncoder 的子类。
(9) indent:默认值为 None。选择最紧凑的表达。如果 indent 是一个非负整数或者字符串,那么 JSON 数组元素和对象成员会被美化输出为该值指定的缩进等级。如果缩进等级为零、负数或者 ""
, 则只会添加换行符。当 indent 为一个正整数时会让每一层缩进同样数量的空格;如果 indent 是一个字符串如换行符、制表符 ( "\n"
、 "\t"
) 等,那么这个字符串会被用于每一层。
(10) separators:默认值为 None。该参数是一个元组,即:(',', ': '
),其中包含空白字符。如果想要得到最紧凑的 JSON 表达式,应指定该参数为:(',',':'
),不要空白字符。
(11) default:默认值为 None。如果要指定该参数,则该参数应是一个函数。每当某个对象无法被序列化时,它就会被调用。它返回该对象的一个可以被 JSON 编码的版本或者引发一个 TypeError (传入参数的类型错误)。如果不指定该参数,则会直接引发 TypeError。
(12) sort_keys:默认值为 False。如果值为True,那么字典的输出会以键的顺序排序。
(13) **kw:其他关键字参数,用于字典。
(14) 返回值:返回 JSON 格式字符串。
在方法或者函数中,如果出现 *
,则表示其后面的参数为命名关键字参数,这是一个特殊的分隔符。在调用时,命名关键字参数必须传入参数名。
2.2 实例演示
2.2.1 将 JSON 格式字符串写入到文件中
定义 JSON 格式字符串,然后使用 dump() 方法将其写入 json 文件,代码如下:
python
# -*- coding: utf-8 -*-
# @Time : 2024-09-14 10:31
# @Author : AmoXiang
# @File: json_demo.py
# @Software: PyCharm
# @Blog: https://blog.csdn.net/xw1680
import json
data1 = [{"a": "Amo", "b": (9, 99), "c": 6.6, "d": 11}]
with open("./tmp/aa.json", "w", encoding='utf8') as file:
json.dump(data1, file, allow_nan=False, sort_keys=True, indent=4)
with open("./tmp/aa.json", "r", encoding='utf8') as file:
data2 = json.load(file) # 注意转换之后得类型 至于json.load文章后面会讲
print(data2) # [{'a': 'Amo', 'b': [9, 99], 'c': 6.6, 'd': 11}] 'b'对应的数据类型都改变了
print(data1 == data2)
print(data1 is data2)
程序运行结果如下图所示:
运行程序将自动生成 aa.json 文件并保存在与程序同级的 tmp
目录下,用 Pycharm 打开效果如上图所示。命名 Python 工程文件时,千万不要使用 Python 保留的标识符以免发生命名冲突。例如,不能将 Python 工程文件命名为 json.py,因为它与 Python 系统模块 json 命名冲突。
2.2.2 防止 ASCII 码写到 json 文件中
当 JSON 格式字符串中出现中文时,使用 dump() 方法会将 ASCII 码写入到文件中,如下图所示:
此时需要将参数 ensure_ascii 的值设置为 False,代码如下:
python
import json
data1 = {
"Title": "Python 常用模块(二):json模块",
"author_info": {"name": "小向", "age": 18}}
with open("./tmp/zw.json", "w", encoding="utf8") as f:
json.dump(data1, f, indent=4, ensure_ascii=False)
程序运行结果如下图所示:
2.2.3 将 csv 文件转换为 json 文件
如果想将本地文件的数据存入 MongoDB
数据库中,该本地文件数据格式必须是 .csv
或者 .json
格式。将 .csv
格式文件存入 MongoDB
数据库时,列元素之间的顺序会错开,因此需要将 .csv
格式文件转换为 .json
格式再存入 MongoDB
数据库。下面使用 dump()
方法将 .csv
格式转换为 .json
格式,代码如下:
python
import json
import csv
csv_f = open("csv_test.csv")
reader = csv.DictReader(csv_f)
# 转换为 json 文件
with open("csv_to_json.json", "w") as file:
for r in reader:
data = json.dump(r, file, ensure_ascii=False, indent=4)
file.write(r"\n")
csv 文件(转换前):
程序运行结果如下图所示:
2.2.4 修改 json 文件中的数据
修改 json 文件的主要思路是:先读取 json 文件中的数据,将数据暂存起来,然后再将修改后的数据写入 json 文件,代码如下:
python
import json
with open("aa.json", "r") as file1:
my_dict = json.load(file1)
my_dict[0]["a"] = "AmoXiang"
with open("aa.json", "w") as file2:
json.dump(my_dict, file2, ensure_ascii=False, indent=4)
程序运行结果如下图所示:
3. dumps() 方法 --- 将 Python 对象转换为 JSON 字符串
3.1 语法参考
dumps() 方法用于将 Python 对象转换为 JSON 格式的字符串。语法格式如下:
python
In [22]: json.dumps?
Signature:
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,
)
Docstring:
Serialize ``obj`` to a JSON formatted ``str``.
If ``skipkeys`` is true then ``dict`` keys that are not basic types
(``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped
instead of raising a ``TypeError``.
If ``ensure_ascii`` is false, then the return value can contain non-ASCII
characters if they appear in strings contained in ``obj``. Otherwise, all
such characters are escaped in JSON strings.
If ``check_circular`` is false, then the circular reference check
for container types will be skipped and a circular reference will
result in an ``RecursionError`` (or worse).
If ``allow_nan`` is false, then it will be a ``ValueError`` to
serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
strict compliance of the JSON specification, instead of using the
JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
If ``indent`` is a non-negative integer, then JSON array elements and
object members will be pretty-printed with that indent level. An indent
level of 0 will only insert newlines. ``None`` is the most compact
representation.
If specified, ``separators`` should be an ``(item_separator, key_separator)``
tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and
``(',', ': ')`` otherwise. To get the most compact JSON representation,
you should specify ``(',', ':')`` to eliminate whitespace.
``default(obj)`` is a function that should return a serializable version
of obj or raise TypeError. The default simply raises TypeError.
If *sort_keys* is true (default: ``False``), then the output of
dictionaries will be sorted by key.
To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
``.default()`` method to serialize additional types), specify it with
the ``cls`` kwarg; otherwise ``JSONEncoder`` is used.
File: f:\dev_tools\python\python310\lib\json\__init__.py
Type: function
dumps() 方法的参数与 dump() 方法的参数使用方法相同,这里不再赘述。
3.2 实例演示
3.2.1 Python 对象转换为 JSON 格式的字符串并按照 JSON 格式缩进显示
通过设置 dumps() 方法的 indent 参数对 JSON 格式的字符串内容进行缩进显示,代码如下:
python
import json
data1 = [{"a": "Amo", "b": (9, 99), "c": 6.6, "d": 11}]
print("正常: ", json.dumps(data1, allow_nan=False, sort_keys=True))
print("缩进显示: ", json.dumps(data1, allow_nan=False, sort_keys=True, indent=2))
程序运行结果如下:
3.2.2 去掉符号后面的空格
dumps() 方法中 separators 参数的作用是去 :以及,
后面的空格,从下面的输出结果能看到 :以及,
后面都有个空格,这是为了美化输出结果。但是在传输数据的过程中,越精简越好,冗余的东西全部去掉可以提高程序运行效率。因此可以通过设置 separators 参数去掉空格,代码如下:
python
import json
data = [{"a": "A", "b": (2, 4), "c": 3.0}]
print(f"原数据: {data}")
print(f"转换为JSON格式字符串: {json.dumps(data)}")
print(f"转换为JSON格式字符串的长度: {len(json.dumps(data))}")
print(f"去掉空格后的长度: {len(json.dumps(data, separators=(',', ':')))}")
print(f"去掉空格后: {json.dumps(data, separators=(',', ':'))}")
程序运行结果如下:
通过运行结果中字符串的长度和去掉空格后的长度对比可以看出,:
和 ,
符号后面的空格被去掉了。
3.2.3 字典类型转换为 JSON 格式字符串
使用 dumps() 方法将 Python 字典类型数据转换为 JSON 格式的字符串,代码如下:
python
import json
a = dict(name="Amo", age=18, QQ="null")
print(a)
print(type(a))
b = json.dumps(a)
print(b)
print(type(b))
程序运行结果如下:
通过类型函数 type() 判断得出:通过 dumps() 方法可以将 Python 字典类型的数据转换为 JSON 格式的字符串。
3.2.4 按照字典排序顺序输出 (a 到 z)
转换后的 JSON 格式字符串是以紧凑的形式输出的,而且也没有顺序,因此 dumps() 方法提供了一些可选的参数,可以提高输出格式的可读性,如参数 sort_keys 可以告诉编码器按照字典排序 (a到z) 输出,代码如下:
python
import json
data = [{"a": "paul", "c": (66, 88), "d": 8.8, "b": "ccc"}]
print(f"原数据: {data}")
print(f"JSON格式的字符串: {json.dumps(data)}")
print(f"排序后JSON格式的字符串: {json.dumps(data, sort_keys=True)}")
程序运行结果如下:
3.2.5 将数组转换为 JSON 格式字符串
使用 dumps() 方法将 Python 列表类型数据转换为 JSON 格式的字符串,代码如下:
python
import json
data = [{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}]
to_json = json.dumps(data)
print(to_json) # [{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}]
print(type(to_json)) # <class 'str'>
3.2.6 将列表转换为 JSON 格式字符串
使用 dumps() 方法将列表转换为 JSON 格式字符串,代码如下:
python
import json
li = ["ID", [1, 2, 3], {"name": "你很棒棒"}] # 创建一个列表
data = json.dumps(li, ensure_ascii=False) # 将列表转换为JSON格式
print(repr(li))
print(data) # 打印JSON格式
4. load() 方法 --- 从 json 文件中读取数据
4.1 语法参考
load() 方法用于从 json 文件中读取数据。语法格式如下:
python
In [23]: json.load?
Signature:
json.load(
fp,
*,
cls=None,
object_hook=None,
parse_float=None,
parse_int=None,
parse_constant=None,
object_pairs_hook=None,
**kw,
)
Docstring:
Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
a JSON document) to a Python object.
``object_hook`` is an optional function that will be called with the
result of any object literal decode (a ``dict``). The return value of
``object_hook`` will be used instead of the ``dict``. This feature
can be used to implement custom decoders (e.g. JSON-RPC class hinting).
``object_pairs_hook`` is an optional function that will be called with the
result of any object literal decoded with an ordered list of pairs. The
return value of ``object_pairs_hook`` will be used instead of the ``dict``.
This feature can be used to implement custom decoders. If ``object_hook``
is also defined, the ``object_pairs_hook`` takes priority.
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
kwarg; otherwise ``JSONDecoder`` is used.
File: f:\dev_tools\python\python310\lib\json\__init__.py
Type: function
参数说明:
(1) fp:一个支持 read() 方法或包含一个 JSON 格式字符串的文本文件或二进制文件。
(2) *:星号本身不是参数。星号表示其后面的参数都是关键字参数,需要使用关键字参数传值,否则程序会出现错误。
(3) cls:可选参数,实例化的类。
(4) object_hook:可选参数,每一个解码出的对象 (即一个字典) 会取代原来的字典。
(5) parse_float:如果指定了该参数,将使用要解码的每个 JSON float 字符串调用。默认情况下为 float 字符串。此参数用于为 JSON 浮点数指定使用另一种数据类型或解析器 (例如 decimal.Decimal)。
(6) parse_int:如果指定该参数,将使用要解码的每个 JSON int 字符串调用。默认情况下为 int 字符串。此参数用于为 JSON 整数指定使用另一种数据类型或解析器 (例如 float)。
(7) parse_constant:如果指定该参数,将为下列字符串之一:
python
'-Infinity', 'Infinity', 'NaN'
如果遇到无效的 JSON 字符串,将引发异常。
(8) object_pairs_hook:可选参数,将使用有序的对象列表对解码的任何对象的结果进行调用。用于实现自定义解码器。如果还定义了 object_hook,则 object_pairs_hook 优先。
(9) **kw:其他关键字参数,用于字典。
(10) 返回值:返回字典。
4.2 实例演示
4.2.1 从 json 文件中读取数据
首先使用 write() 方法将字典类型数据写入到一个名为 amo.json 的文件中,然后使用 load() 函数读取该文件中的数据并输出,代码如下:
python
import json
with open("amo.json", "w+") as file: # 打开json文件
# 注意一定要是 外单'' 内部的为"" 否则程序会报错
file.write('[{"a":"A","c":3.0,"b":[2,4]}]') # 写入数据
file.flush() # 刷新缓冲区
file.seek(0) # 移动文件,读取指针到指定位置
print(json.load(file)) # 读取数据: [{'a': 'A', 'c': 3.0, 'b': [2, 4]}]
4.2.2 读取文本数据并将其转换为JSON格式( 从TXT文本中解析JSON格式)
首先使用 open() 方法读取文本文件 amo.txt 中的数据,然后使用 load() 函数将其转换为 JSON 格式并输出其中的人物名称信息,代码如下:
python
import json
with open("amo.txt", "r") as file: # 打开文本文件
data = json.load(file) # 读取数据
for line in data: # 遍历数据输出人物姓名
print(line["person"])
4.2.3 向原有 json 文件追加数据
json 文件 student.json 保存了三条学生姓名数据,如下图所示:
下面以追加方式打开该文件,然后添加两条新数据,代码如下:
python
import json
with open("student.json", "a+") as file: # 以追加方式打开文件
file.seek(0) # 默认偏移量在最后,调整到开头
if file.read() == "": # 判断是否为空,如果为空创建一个新字典
data = {}
else:
file.seek(0)
data = json.load(file)
# 追加内容
data["04"] = "诸葛村夫"
data["05"] = "司马懿"
with open("student.json", "w") as file:
json.dump(data, file, ensure_ascii=False)
程序运行结果如下图所示:
5. loads() 方法 --- 将 JSON 格式转换成 Python 字典
5.1 语法参考
loads() 方法用于将 JSON 格式字符串转换成 Python 字典对象。语法格式如下:
python
In [24]: json.loads?
Signature:
json.loads(
s,
*,
cls=None,
object_hook=None,
parse_float=None,
parse_int=None,
parse_constant=None,
object_pairs_hook=None,
**kw,
)
Docstring:
Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance
containing a JSON document) to a Python object.
``object_hook`` is an optional function that will be called with the
result of any object literal decode (a ``dict``). The return value of
``object_hook`` will be used instead of the ``dict``. This feature
can be used to implement custom decoders (e.g. JSON-RPC class hinting).
``object_pairs_hook`` is an optional function that will be called with the
result of any object literal decoded with an ordered list of pairs. The
return value of ``object_pairs_hook`` will be used instead of the ``dict``.
This feature can be used to implement custom decoders. If ``object_hook``
is also defined, the ``object_pairs_hook`` takes priority.
``parse_float``, if specified, will be called with the string
of every JSON float to be decoded. By default this is equivalent to
float(num_str). This can be used to use another datatype or parser
for JSON floats (e.g. decimal.Decimal).
``parse_int``, if specified, will be called with the string
of every JSON int to be decoded. By default this is equivalent to
int(num_str). This can be used to use another datatype or parser
for JSON integers (e.g. float).
``parse_constant``, if specified, will be called with one of the
following strings: -Infinity, Infinity, NaN.
This can be used to raise an exception if invalid JSON numbers
are encountered.
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
kwarg; otherwise ``JSONDecoder`` is used.
File: f:\dev_tools\python\python310\lib\json\__init__.py
Type: function
参数说明:
(1) s:包含 JSON 格式字符串,字节或字节数组的实例。
(2) *:星号本身不是参数。星号表示其后面的参数都是关键字参数,需要使用关键字参数传值,否则程序会出现错误。
(3) encoding:表示编码方式。
(4) cls:可选参数,实例化的类。
(5) object_hook:可选参数,每一个解码出的对象 (即一个字典) 会取代原来的字典。
(6) parse_float:如果指定了该参数,将使用要解码的每个 JSON float 字符串调用。默认情况下为 float 字符串。此参数用于为 JSON 浮点数指定使用另一种数据类型或解析器 (例如 decimal.Decimal)。
(7) parse_int:如果指定该参数,将使用要解码的每个 JSON int 字符串调用。默认情况下为 int 字符串。此参数用于为 JSON 整数指定使用另一种数据类型或解析器 (例如 float)。
(8) parse_constant:如果指定该参数,将为下列字符串之一:
python
'-Infinity', 'Infinity', 'NaN'
如果遇到无效的 JSON 字符串,将引发异常。
(9) object_pairs_hook:可选参数,将使用有序的对象列表对解码的任何对象的结果进行调用。用于实现自定义解码器。如果还定义了 object_hook,则 object_pairs_hook 优先。
(10) **kw:其他关键字参数,用于字典。
(11) 返回值:返回字典。
5.2 实例演示
5.2.1 简单读取 json 文件中的数据
使用 loads() 方法读取 json 文件中的数据。例如,读取 city.json 文件中的城市信息,代码如下:
python
import json
with open("city.json", "r") as file: # 打开json文件
data = file.read() # 读取json文件
print(type(data)) # 输出数据类型
result = json.loads(data) # 将json字符串转换为字典
print(result)
new_result = json.dumps(result, ensure_ascii=False) # 将字典转换为json字符串
print(new_result)
5.2.2 将 JSON 格式转换为字典
使用 loads() 方法将 JSON 格式字符串转换为字典类型,代码如下:
python
import json
with open("city.json", "r") as file:
data = file.read()
print(type(data)) # <class 'str'>
val = json.loads(data)
print(type(val)) # <class 'dict'>
print(val)
6. JSONDecodeError() 方法 --- 返回解码错误信息
6.1 语法参考
JSONDecodeError() 方法用于返回解码错误信息。语法格式如下:
python
def __init__(self, msg, doc, pos)
msg: 表示未格式化的错误信息。
doc: 表示正在解析的 JSON 文档。
pos: 表示解析失败的 doc 的起始索引。
返回值: 返回 JSONDecodeError 错误信息
6.2 实例演示
6.2.1 单双引号使用不当导致 JSONDecodeError 错误
先来看一段代码:
python
import json
data = "{'01': '跟着Amo学Python'}"
data = json.loads(data)
print(data)
程序运行结果如图所示:
运行程序,出现了 JSONDecodeError 错误。现将上述代码稍作修改:
python
import json
data = '{"01": "跟着Amo学Python"}'
data = json.loads(data)
print(data)
程序运行结果如下:
text
{'01': '跟着Amo学Python'}
这里需要注意的是,虽然在 Python 中单双引号的作用一样,但是在具体应用中还是有一些不同的地方。