【吐血整理】Python 常用模块(二):json 模块
【摘要】 目录 1. json 模块介绍1.1 json 模块快用导航1.2 什么是 JSON1.3 json 模块 2. dump() 方法 --- 转换为 JSON 格式写入文件2.1 语法参考2.2 实例演示2.2.1 将 JSON 格式字符串写入到文件中2.2.2 防止 ASCII 码写到 json 文件中2.2.3 将 csv 文件转换为 json 文件2....
目录
博主发现当我们自己不知道
Python
某个模块的用法时,自己又没有相关笔记什么的,一般人很少去官网进行查阅,然后在网上乱找一通,描述的也不详细,非常地浪费时间,故博主决定自己将常用模块中常用的方法进行总结,以便后期自己查阅和网上的朋友们查找学习。今天开始总结我们的第二个常用模块:json
模块。
Python 中的 json
模块提供了对 JSON
的支持,用于将 JSON
格式字符串转换为 Python
对象。首先需要了解一下什么是 JSON
。
1. json 模块介绍
1.1 json 模块快用导航
1.2 什么是 JSON
JSON
是基于 JavaScript
语言的轻量级的数据交换格式,是 JavaScript
对象的表示法 (JavaScript Object Notation),它是用来存储和交换文本信息的。信息表示格式为:
- 数据在名称 / 值对中。
- 数据由逗号分隔。
- 大括号保存对象。
- 方括号保存数组。
例如,下面的格式:
{ "login": [ {"password": "123456", "username": "AmoXiang"}, {"password": "123", "username": "你很棒棒"}, {"password": "111", "username": "xw1680"}, ]
}
上述代码中的 username
:AmoXiang
和 password
:123456
等叫作 JSON
对象,它们一般放在大括号 {}
中,login
为 JSON
数组,用方括号 []
表示。
1.3 json 模块
Python 中的 json 模块提供了对 JSON 的支持,它既包含了将 JSON 格式字符串转换为 Python 对象的方法,也提供了将 Python 对象转换为 JSON 格式字符串的方法,如下图所示。
2. dump() 方法 — 转换为 JSON 格式写入文件
2.1 语法参考
dump()
方法用于将 Python 对象转换为 JSON 格式字符串后写入到文件中。语法格式如下:
def 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):
参数说明:
(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 文件,代码如下:
import json
data1 = [{"a": "Amo", "b": (9, 99), "c": 6.6, "d": 11}]
with open("aa.json", "w") as file: json.dump(data1, file, allow_nan=False, sort_keys=True, indent=4)
程序运行结果如下图所示:
运行程序将自动生成 aa.json 文件并保存在程序所在路径下,用记事本打开效果如上图所示。
命名 Python 工程文件时,千万不要使用 Python 保留的标识符以免发生命名冲突。例如,不能将 Python 工程文件命名为 json.py,因为它与 Python 系统模块 json 命名冲突。
2.2.2 防止 ASCII 码写到 json 文件中
当 JSON 格式字符串中出现中文时,使用 dump() 方法会将 ASCII 码写入到文件中,如下图所示:
此时需要将参数 ensure_ascii 的值设置为 False,代码如下:
import json
data1 = { "Title": "【吐血整理】Python 常用模块(二):json 模块", "author_info": {"name": "小向", "age": 18}}
with open("zw.json", "w") 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
格式,代码如下:
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 文件中的数据
![](https://img-blog.csdnimg.cn/20201207095910460.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h3MTY4MA==,size_16,color_FFFFFF,t_70)
修改 json 文件的主要思路是:先读取 json 文件中的数据,将数据暂存起来,然后再将修改后的数据写入 json 文件,代码如下:
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 格式的字符串。语法格式如下:
def 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):
dumps() 方法的参数与 dump() 方法的参数使用方法相同,这里不再赘述。
3.2 实例演示
3.2.1 Python 对象转换为 JSON 格式的字符串并按照 JSON 格式缩进显示
通过设置 dumps() 方法的 indent 参数对 JSON 格式的字符串内容进行缩进显示,代码如下:
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 参数去掉空格,代码如下:
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 格式的字符串,代码如下:
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) 输出,代码如下:
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.dumps(data,sort_keys=True)}")
程序运行结果如下:
3.2.5 将数组转换为 JSON 格式字符串
使用 dumps() 方法将 Python 数组类型数据转换为 JSON 格式的字符串,代码如下:
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)) #
3.2.6 将列表转换为 JSON 格式字符串
使用 dumps() 方法将列表转换为 JSON 格式字符串,代码如下:
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 文件中读取数据。语法格式如下:
def load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
参数说明:
(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:如果指定该参数,将为下列字符串之一:
'-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() 函数读取该文件中的数据并输出,代码如下:
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 格式并输出其中的人物名称信息,代码如下:
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 保存了三条学生姓名数据,如下图所示:
下面以追加方式打开该文件,然后添加两条新数据,代码如下:
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 字典对象。语法格式如下:
def loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
参数说明:
(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:如果指定该参数,将为下列字符串之一:
'-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 文件中的城市信息,代码如下:
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 格式字符串转换为字典类型,代码如下:
import json
with open("city.json", "r") as file: data = file.read() print(type(data)) # val = json.loads(data) print(type(val)) # print(val)
6. JSONDecodeError() 方法 — 返回解码错误信息
6.1 语法参考
JSONDecodeError() 方法用于返回解码错误信息。语法格式如下:
def __init__(self, msg, doc, pos)
msg: 表示未格式化的错误信息。
doc: 表示正在解析的 JSON 文档。
pos: 表示解析失败的 doc 的起始索引。
返回值: 返回 JSONDecodeError 错误信息
6.2 实例演示
6.2.1 单双引号使用不当导致 JSONDecodeError 错误
先来看一段代码:
import json
data = "{'01': '跟着Amo学Python'}"
data = json.loads(data)
print(data)
程序运行结果如图所示:
运行程序,出现了 JSONDecodeError 错误。现将上述代码稍作修改:
import json
data = '{"01": "跟着Amo学Python"}'
data = json.loads(data)
print(data)
程序运行结果如下:
{'01': '跟着Amo学Python'}
这里需要注意的是,虽然在 Python 中单双引号的作用一样,但是在具体应用中还是有一些不同的地方。