目录
1、基本概念
2、JSON模块
2.1、dumps() 与 loads() 函数
2.2、dump() 与 load() 函数
2.3、bool 、None 类型的序列化与反序列化
3、pickle模块
3.1、dumps() 与 loads() 函数
3.2、dump() 与 load() 函数
1、基本概念
说明:通过文件操作,可将字符串写入到一个本地文件,但是无法将一个对象,如字典,列表,元组直接写入到一个文件里,这是就需要将这个对象进行序列化,然后写入文件。
序列化:把内存中的数据转换为字节序列,保存到文件。
反序列化:从文件的字节序列恢复到内存中。
类比:字符串与 byte 类型之间互相转换常用的 encode() 函数、与 decode() 函数,分别代表着编码与解码。
Python中可序列化数据类型
- 可序列化:number、str、list、tuple、dict 字典是最常用的序列化数据类型
- 不可序列化:class 、def (函数与实例化对象)、set 是无法进行序列化的
在Python中有两个模块可以实现序列化和非序列化,分别是json 和 pickle,下面分别说明两者的使用和区别
2、JSON模块
JSON一种轻量级的数据交换标准,JSON的本质是字符串。也是一个通用的序列化模块,通过它可以完成通用化的序列化与反序列化操作。因为几乎所有的编程语言都有json模块,而且他们序列化与反序列化的规则是统一的。
2.1、dumps() 与 loads() 函数
注意:这两个函数不能直接和文件交互,需要将对象序列化后再写入文件,将原数据从文件中读出后再进行反序列化操作。
示例1:序列化操作
import json# 定义 整型、字符串、列表、元组、字典 五种数据类型 ,用于序列化测试
int_test = 666
str_test = 'test_string'
list_test = [1, 2, 3]
tuple_test = (4, 5, 6)
dict_test = {'Name': '林一', 'Sex': '男', 'Age': '20'}int_test_json = json.dumps(int_test)
print(int_test_json) # 666str_test_json = json.dumps(str_test)
print(str_test_json) # "test_string"list_test_json = json.dumps(list_test)
print(list_test_json) # [1, 2, 3]tuple_test_json = json.dumps(tuple_test)
print(tuple_test_json) # [4, 5, 6]dict_test_json = json.dumps(dict_test)
print(dict_test_json) # {"Name": "\u6797\u4e00", "Sex": "\u7537", "Age": "20"}
从执行结果可以看出字典类型的数据类型,经过序列化后。字典变成了字符串的同时,且字典内的 单引号 变成了 双引号,中文也变成了比特类型,并且进行了 encode 。
示例2:反序列化操作
# 反序列化操作
print(json.loads(int_test_json)) # 666
print(json.loads(str_test_json)) # test_string
print(json.loads(list_test_json)) # [1, 2, 3]
print(json.loads(tuple_test_json)) # [4, 5, 6]
print(json.loads(dict_test_json)) # {'Name': '林一', 'Sex': '男', 'Age': '20'}
注意:元组类型经过序列化处理后再通过反序列化还原数据时,会变为列表数据类型。
- 这是因为 元组类型 是 python 语言中特有的数据类型,json 作为一个通用格式,无法识别元组类型。所以在针对元组类型进行序列化的时候,会先将 元组类型 ,先转为 列表,再进行序列化处理;同样的在进行反序列化处理时,就会将序列化后的 元组类型 ,又转成了 列表类型 。(类型的转换,不影响对数据的使用)
2.2、dump() 与 load() 函数
作用:可以直接和文件交互
示例1:序列化
dict_test = {"Name": "hello", "Sex": "女", "Age": 18}
with open("json_test.txt", "w") as f:json.dump(dict_test, f)
示例2:反序列化
with open("json_test.txt", "r") as f:content = json.load(f)print(f"文件类型是: {type(content)}, 文件内容为: {content}")
2.3、bool 、None 类型的序列化与反序列化
import json
print("-------------------序列化----------------------------")
print(json.dumps(True)) # true
print(json.dumps(False)) # false
print(json.dumps(None)) # nullprint("-------------------反序列化----------------------------")
print(json.loads(json.dumps(True))) # True
print(json.loads(json.dumps(False))) # False
print(json.loads(json.dumps(None))) # None
说明:从上述运行结果来看,bool 类型经过序列化处理后,变成了小写的 true、false;而 None 类型则变成了 小写的 null 。经过反序列化之后,bool、None 类型又被还原成了 python 可读的状态。
注意:大多数的编程语言中, bool 类型都是小写的 true、false 。json 作为一个通用的序列化模块,也同样遵循着这种规则。(小写的 true、false 依然是字符串类型。 )
3、pickle模块
说明:pickle模块与json模块一样可以进行序列化与反序列化,区别在于 pickle 是 Python 内置的序列化模块,它只能用于 python 自身来使用,而json模块更加通用,但pickle模块的性能是要比 json 更好的。所以实际使用根据自身需求选择对应的模块进行使用。
3.1、dumps() 与 loads() 函数
注意:区别于 json 模块,pickle 模块的 dumps() 函数 返回的是 byte 类型 ,而 loads() 函数也仅支持 byte 类型的 pickle 序列进行反序列化的操作。
示例1: 序列化与反序列化
import pickle# 定义 字符串、元组、字典 三种数据类型 ,用于序列化测试
print("-------------------序列化----------------------------")
str_test = 'test_string'
tuple_test = (4, 5, 6)
dict_test = {'Name': '林一', 'Sex': '男', 'Age': '20'}str_test_pickle = pickle.dumps(str_test)
print(str_test_pickle)tuple_test_pickle = pickle.dumps(tuple_test)
print(tuple_test_pickle)dict_test_pickle = pickle.dumps(dict_test)
print(dict_test_pickle)print("-------------------反序列化----------------------------")
print(pickle.loads(str_test_pickle))
print(pickle.loads(tuple_test_pickle))
print(pickle.loads(dict_test_pickle))
3.2、dump() 与 load() 函数
作用:dump()函数能一个接着一个地将几个对象序列化存储到同一个文件中,随后调用load()来以同样的顺序反序列化读出这些对象。
参数protocol:是序列化模式,默认是0(ASCII协议,表示以文本的形式进行序列化),protocol的值还可以是1和2(1和2表示以二进制的形式进行序列化。其中,1是老式的二进制协议;2是新二进制协议)。
示例:序列化与反序列化
import pickle
dict_test = {"Name": "hello", "Sex": "女", "Age": 18}
with open("pickle_test.txt", "wb") as f:pickle.dump(dict_test, f, 0)with open("pickle_test.txt", "rb") as f:content = pickle.load(f)print(f"文件类型是: {type(content)}, 文件内容为: {content}")
注意:
- 1、由于写入文件和从文件读出都是以二进制的形式,所以,读写是的模式必须是:wb, rb.
- 2、为避免写入文件的内容乱码,在dump()里加上第三个参数,设为0(ASCII协议).