python json序列化模块
一、json
Json模块提供了四个功能:dumps、dump、loads、load
1、前景
什么叫序列化——将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化。
序列化的目的
- 以某种存储形式使自定义对象持久化;
- 将对象从一个地方传递到另一个地方。
- 使程序更具维护性
在Python中,能够进行序列化的前提是被序列化的对象必须是JSON兼容的数据类型。JSON兼容的数据类型包括:
- 字典(Dictionary):键值对的集合,键必须是字符串类型。
- 列表(List):有序的元素集合。
- 字符串(String):由一系列字符组成的文本。
- 数字(Number):包括整数(int)和浮点数(float)。
- 布尔值(Boolean):表示真或假的值,即True或False。
- None:表示空值或缺失值的特殊类型。
2、loads和dumps(反序列化和序列化)
也可以处理嵌套的数据类型
序列化,将字典序列化成一个字符串
json.dumps(dic)
1 2 3 4 | dic = { 'k1' : 'v1' , 'k2' : 'v2' , 'k3' : 'v3' } str_dic = json.dumps(dic) # 序列化:将一个字典转换成一个字符串 print ( type (str_dic), str_dic) # <class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"} # 注意,json转换完的字符串类型的字典中的字符串是由""表示的 |
反序列化,将字符串转成字典
json.loads(str_dic)
1 2 3 4 5 | dic = { 'k1' : 'v1' , 'k2' : 'v2' , 'k3' : 'v3' } str_dic = json.dumps(dic) dic2 = json.loads(str_dic) # 反序列化:将一个字符串格式的字典转换成一个字典 # 注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示 print ( type (dic2), dic2) # <class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} |
序列化字符串
1 2 3 4 5 6 7 8 | import json string_data = 'Hello, World!' # 序列化字符串 json_str = json.dumps(string_data) print (json_str) # 反序列化 res = json.loads(json_str) print (res) |
3、load和dump(反序列化读和序列化写)
json.dump(data, f),data要是可迭代的容器,字典或者列表
注意⚠️:
使用 json.dump()
方法来序列化一个字符串写入文件时,需要将字符串包装在一个可迭代的容器中,例如列表或字典
例如字符串:
1 2 3 4 5 6 7 8 9 10 | import json string_data = "Hello, World!" # 创建包含字符串的字典 data = { 'message' : string_data} # 序列化字符串并写入文件 with open ( 'output.json' , 'w' ) as f: json.dump(data, f) |
列表:列表是可迭代对象可以直接序列化写
1 2 3 4 5 6 7 | import json list_data = [ 1 , 2 , 3 , 4 , 5 ] # 序列化列表并写入文件 with open ( 'output.json' , 'w' ) as f: json.dump(list_data, f) |
序列化写字典
1 2 3 4 5 6 7 | with open ( 'a.txt' , 'w' ) as f: dic = { 'k1' : 'v1' , 'k2' : 'v2' , 'k3' : 'v3' } json.dump(dic, f) # dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件 with open ( 'a.txt' , 'r' ) as f: dic2 = json.load(f) # load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回 print ( type (dic2), dic2) # <class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} |
案例:
登录注册时候,数据的写入和读取
json.load(f)
函数用于从文件中加载 JSON 数据,但是它只能读取一个合法的 JSON 对象,当文本f
中,存在多个 JSON 对象,导致出现错误。要解决这个问题,将文本中的每个 JSON 对象分别解析处理。可以使用
json.loads()
函数逐行解析每个 JSON 对象,然后进行处理。
换行处理
1 2 | json.dump(data, f, ensure_ascii = True ) f.write( '\n' ) |
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import json username, password, role = input ( 'Username:' ).split() data = { 'username' : username, 'password' : password, 'role' : role } with open ( 'user_data.txt' , "r" , encoding = 'utf-8' ) as f: lines = f.readlines() for line in lines: line = line.strip() # 去除行首行尾的空白字符 obj = json.loads(line) if username = = obj[ 'username' ]: print ( '用户已经注册过了!' ) break else : with open ( 'user_data.txt' , "a" , encoding = 'utf-8' ) as f: json.dump(data, f, ensure_ascii = True ) f.write( '\n' ) # f.write(f"{username},{password},{role}\n") print (f "用户 {data['username']} 已成功注册!" ) with open ( 'user_data.txt' , "r" , encoding = "utf-8" ) as f: lines = f.readlines() for line in lines: line = line.strip() # 去除行首行尾的空白字符 if line: # 确保行不为空 try : obj = json.loads(line) # 在这里对每个 JSON 对象进行处理 print (obj, type (obj)) except json.JSONDecodeError: print ( '无效的 JSON 数据:' , line) |
4、ensure_ascii关键字参数
汉字的序列化后为\u56fd\u7c4d,使用ensure_ascii关键字参数可以以中文写入
1 2 3 4 5 6 7 8 9 10 11 12 | with open ( 'a.txt' , 'a' ) as f: json.dump({ '国籍' : '中国' }, f) # 序列化方式写文件 ret = json.dumps({ '国籍' : '中国' }) f.write(ret + '\n' ) # 正常通用方式写文件、 # {"\u56fd\u7c4d": "\u4e2d\u56fd"}{"\u56fd\u7c4d": "\u4e2d\u56fd"} json.dump({ '国籍' : '美国' }, f, ensure_ascii = False ) # 取消编码写入 ret = json.dumps({ '国籍' : '美国' }, ensure_ascii = False ) f.write(ret + '\n' ) # {"国籍": "美国"}{"国籍": "美国"} |
5、格式化输出(indent)
json.dumps()
是 json
模块中的一个函数,用于将 Python 对象序列化为 JSON 字符串。它提供了一些参数来控制序列化的行为。下面是对 json.dumps()
中的常用序列化参数的解释:
-
sort_keys
(可选参数):设置为True
时,将按照键的字母顺序对字典进行排序,默认为False
。 -
indent
(可选参数):指定缩进级别,用于生成格式化的 JSON 字符串。可以是一个整数,表示缩进的空格数,或者是一个字符串,表示使用的缩进字符(例如,\t
表示使用制表符进行缩进)。默认为None
,表示不进行格式化,生成紧凑的 JSON 字符串。 -
separators
(可选参数):指定分隔符,用于控制生成的 JSON 字符串中的各个部分之间的分隔符。它是一个包含两个字符串的元组,第一个字符串用于分隔键和值之间的分隔符,默认为","
;第二个字符串用于分隔键值对之间的分隔符,默认为":"
。 -
ensure_ascii
(可选参数):设置为True
时,所有非 ASCII 字符将被转义为 ASCII 编码的字符序列,默认为True
。如果需要生成包含非 ASCII 字符的 JSON 字符串,可以将其设置为False
。
1 2 3 4 5 | import json data = { 'username' : [ '李四' , '银行职员' ], 'sex' : 'male' , 'age' : 16 } json_dic2 = json.dumps(data, sort_keys = True , indent = 2 , separators = ( ',' , ':' ), ensure_ascii = False ) print (json_dic2) |
# 输出结果
sort_keys=True
:按照键的字母顺序对字典进行排序。indent=2
:使用两个空格进行缩进,生成格式化的 JSON 字符串。separators=(',', ':')
:使用逗号和冒号作为分隔符。ensure_ascii=False
:允许非 ASCII 字符在生成的 JSON 字符串中原样显示。
二、pickle 模块
1、用于序列化的两个模块
- json,用于字符串 和 python数据类型间进行转换 (可以跨语言使用)
- pickle,用于python特有的类型 和 python的数据类型间进行转换
- pickle 能够转换所有的pyhton数据类型、序列化后为二进制
- json只能转换部分的python数据类型
2、pickle模块提供了四个功能:dumps(序列化)、dump(序列化写)、loads(反序列化)、load(反序列化读)
(不仅可以序列化字典,列表...可以把python中任意的数据类型序列化)
序列化和反序列化
1 2 3 4 5 6 7 8 9 | import pickle dic = { 'k1' : 'v1' , 'k2' : 'v2' , 'k3' : 'v3' } str_dic = pickle.dumps(dic) print (str_dic) # 一串二进制内容 # b'\x80\x03}q\x00(X\x02\x00\x00\x00k1q\x01X\x02\x00\x00\x00v1q\x02X\x02\x。。。 dic2 = pickle.loads(str_dic) print (dic2) # 字典 {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} |
3、序列化写、读
1 2 3 4 5 6 7 8 9 10 11 | import pickle import time struct_time = time.localtime( 1000000000 ) print (struct_time) with open ( 'a.txt' , 'wb' ) as f: pickle.dump(struct_time, f) with open ( 'a.txt' , 'rb' ) as f1: struct_time2 = pickle.load(f1) print (struct_time2.tm_year) |