序列化模块
5.15.6 序列化模块
序列化的本质就是将一种数据结构(如字典、列表)等转换成一个特殊的序列(字符串或者bytes)的过程就叫做序列化。
序列化模块就是将一个常见的数据结构转化成一个特殊的序列,并且这个特殊的序列还可以反解回去。它的主要用途:文件读写数据,网络传输数据。
1、序列化的目的
- 以某种存储形式使自定义对象持久化;
内存是无法永久保存数据的,当程序运行了一段时间,我们断点或者重启程序,内存中关于这个程序的之前一段时间的数据都被清空了。但是在在断电或重启程序之前将程序当前内存中所有的数据都保存在文件中,以便下次程序执行能够从文件中载入之前的数据,然后继续执行。
- 将对象从一个地方传递到另一个地方。
序列化时不仅可以吧序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发双方约定好使用一种序列化的格式,那边打破了平台、语言差异化带来的限制,实现了跨平台数据交互。
- 使程序更具维护性。
2、Python中这种序列化模块有三种:
json模块:
-
不同语言都遵循的一种数据转化格式,即不同语言都使用的特殊字符串。(比如Python的一个列表[1, 2, 3]利用json转化成特殊的字符串,然后在编码成bytes发送给php的开发者,php的开发者就可以解码成特殊的字符串,然后在反解成原数组(列表): [1, 2, 3])
-
json序列化只支持部分Python数据结构:dict,list, tuple,str,int, float,True,False,None
pickle模块:
-
只能是Python语言遵循的一种数据转化格式,只能在python语言中使用。
-
支持Python所有的数据类型包括实例化对象。
shelve模块:
- 类似于字典的操作方式去操作特殊的字符串。
3、json模块
json模块是将满足条件的数据结构转化成特殊的字符串,并且也可以反序列化还原回去。
序列化模块总共只有两种用法,要不就是用于网络传输的中间环节,要不就是文件存储的中间环节,所以json模块总共就有两对四个方法:
用于网络传输:dumps、loads
用于文件写读:dump、load
- dumps, loads
import json
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转换完的字符串类型的字典中的字符串是由""表示的
#反序列化:将一个字符串格式的字典转换成一个字典
dic2 = json.loads(str_dic)
#注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
print(type(dic2),dic2)
#<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
import json
list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}]
# 也可以处理嵌套的数据类型
str_dic = json.dumps(list_dic)
print(type(str_dic),str_dic)
#<class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}]
list_dic2 = json.loads(str_dic)
print(type(list_dic2),list_dic2)
#<class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
- dump, load
import json
f = open('json_file.json','w')
dic = {'k1':'v1','k2':'v2','k3':'v3'}
# dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
json.dump(dic,f)
f.close()
# json文件也是文件,就是专门存储json字符串的文件。
f = open('json_file.json')
# load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
dic2 = json.load(f)
f.close()
print(type(dic2),dic2)
json序列化存储多个数据到同一个文件中
对于json序列化,存储多个数据到一个文件中是有问题的,默认一个json文件只能存储一个json数据,但是也可以解决,
dic1 = {'name':'oldboy1'}
dic2 = {'name':'oldboy2'}
dic3 = {'name':'oldboy3'}
f = open('序列化',encoding='utf-8',mode='a')
str1 = json.dumps(dic1)
f.write(str1+'\n')
str2 = json.dumps(dic2)
f.write(str2+'\n')
str3 = json.dumps(dic3)
f.write(str3+'\n')
f.close()
f = open('序列化',encoding='utf-8')
for line in f:
print(json.loads(line))
4、pickle模块
pickle模块是将Python所有的数据结构以及对象等转化成bytes类型,然后还可以反序列化还原回去。
pickle只是Python语言使用,它支持Python所有的数据类型包括后面我们要讲的实例化对象等,它能将这些所有的数据结构序列化成特殊的bytes,然后还可以反序列化还原。使用上与json几乎差不多,也是两对四个方法。
用于网络传输:dumps、loads
用于文件写读:dump、load
- dumps, loads
import pickle
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = pickle.dumps(dic)
print(str_dic) # bytes类型
dic2 = pickle.loads(str_dic)
print(dic2) #字典
- dump, load
dic = {(1,2):'zhangsan',1:True,'set':{1,2,3}}
f = open('pick序列化',mode='wb')
pickle.dump(dic,f)
f.close()
with open('pick序列化',mode='wb') as f1:
pickle.dump(dic,f1)
pickle序列化存储多个数据到一个文件中
dic1 = {'name':'zhnagsan'}
dic2 = {'name':'lisi'}
dic3 = {'name':'wangwu'}
f = open('pick多数据',mode='wb')
pickle.dump(dic1,f)
pickle.dump(dic2,f)
pickle.dump(dic3,f)
f.close()
f = open('pick多数据',mode='rb')
while True:
try:
print(pickle.load(f))
except EOFError:
break
f.close()
既然pickle如此强大,为什么还要学json呢?这里我们要说明一下,json是一种所有的语言都可以识别的数据结构。如果我们将一个字典或者序列化成了一个json存在文件里,那么java代码或者js代码也可以拿来用。但是如果我们用pickle进行序列化,其他语言就不能读懂这是什么了。
所以,如果你序列化的内容是列表或者字典,我们非常推荐你使用json模块,但如果出于某种原因你不得不序列化其他的数据类型,而未来你还会用python对这个数据进行反序列化的话,那么就可以使用pickle。
5、json与pickle的不同
json序列化除了可以解决写入文件的问题,还可以解决网络传输的问题,比如你将一个list数据结构通过网络传给另个开发者,那么你不可以直接传输,之前我们说过,你要想传输出去必须用bytes类型。但是bytes类型只能与字符串类型互相转化,它不能与其他数据结构直接转化,所以,你只能将list ---> 字符串 ---> bytes 然后发送,对方收到之后,在decode() 解码成原字符串。
此时这个字符串不能是我们之前学过的str那种字符串,因为它不能反解,必须要是这个特殊的字符串,他可以反解成list 这样开发者之间就可以借助网络互传数据了,不仅仅是开发者之间,你要借助网络爬取数据这些数据多半是这种特殊的字符串,你接受到之后,在反解成你需要的数据类型。

浙公网安备 33010602011771号