您的位置:首页 > 编程语言 > Python开发

Python3 序列化json、pickle、shelve

2019-01-21 16:39 573 查看

序列化

 

将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化。

序列化就是将字典列表等转化成字符串存到文档中,反序列化就是把字符串读出来,在还原成列表、字典等属性。

 

序列化的目的

1、以某种存储形式使自定义对象持久化;

2、将对象从一个地方传递到另一个地方。

3、使程序更具维护性。

json

 

Json模块提供了四个功能:dumps、dump、loads、load

[code]import json
# 将一个对象转换成一个能够永久存储的内容

dic = {'name':'meet','age':18}
# dump
# 将一个对象转换成一个文件的时候-->序列化-->dump(要转换的对象,文件句柄)-->可见文件
f = open('test.txt','w',encoding='utf-8')
json.dump(dic,f)                               # 写入文件

# load
# 将一个文件转换成一个对象的时候-->反序列化-->load(文件句柄)--> 对象
f = open('test.txt','r',encoding='utf-8')
s = json.load(f)
print(type(s),s)  #<class 'dict'> {'name': 'meet', 'age': 18}

lst = [1,2,3,[4,5,6]]
# dumps
#将一个对象转换成一个字符串的时候--> 序列化--> dumps(要转换的对象)-->字符串
s = json.dumps(lst)
print(type(s),s)       #<class 'str'> [1, 2, 3, [4, 5, 6]]

# loads
# 将一个字符串转换成一个对象的时候--> 反序列化-->loads(要转换的字符串)-->对象
l = json.loads(s)
print(type(l),l)       #<class 'list'> [1, 2, 3, [4, 5, 6]]

 

pickle

pickle模块提供了四个功能:dumps、dump、loads、load

 

[code]import pickle
# pickle是python特有的模块,将对象转化成二进制进行操作
# 将一个对象转换成一个能够永久存储的内容

# dumps
# 将一个对象转换成文件的时候-->序列化-->dump(要转换的对象,文件句柄)-->不可见文件
dic = {'1':2,'2':3}
pickle.dump(dic,f)

# loads
# 将一个文件转换成一个对象的时候--> 反序列化--> load(文件句柄) --> 对象
f1 = open('test.txt','rb')
s = pickle.load(f1)
print(type(s),s)      # <class 'dict'> {'1': 2, '2': 3}

dic = {'1':2,'2':3}
# dumps
# 将一个对象转换成一个字节的时候--> 序列化-->dumps(要转换的对象)-->字节
s = pickle.dumps(dic) # 将对象转换成字节
print(type(s),s)      #<class 'bytes'>
#b'\x80\x03}q\x00(X\x01\x00\x00\x001q\x01K\x02X\x01\x00\x00\x002q\x02K\x03u.'

# loads
# 将一个字节转换成一个对象的时候--->反序列化-->loads(要转换的字节)-->对象
c = pickle.loads(s)  # 将字节转换成对象
print(type(c),c)     # <class 'dict'> {'1': 2, '2': 3}

shelve

shelve模块是一个序列化的包,跟json和pickle模块功能相似,且是基于pickle模块升级的,功能一致代码更加简洁,同样不能序列化lambda匿名函数。

[code]import shelve
f = shelve.open('test')
执行后会产生3个文件
test.bak   # bak文件就是备份的
test.dat   # 文件内容不可视
test.dir   # 展示如.bak文件
这些都是在windos系统下生成的文件,平时不要修改、删除任何一个文件,会导致文件出错。
而在mac系统下生成一个文件test.db

 

如下是pickle模块和shelve模块对字典进行增加数据操作的对比:

 

[code]# 如下是我们使用pickle模块对字典进行增加数据的操作
import pickle
f = open('test','wb')# 首先我们需要打开一个文件
dic = {'name':'macks'}
pickle.dump(dic,f)# 将dic字典序列化到这test文件中

f1 = open('test','rb')#然后再打开这个文件
dics = pickle.load(f1)# 将这个文件中的内容反序列出来,附给一个新的变量
print(dics)

dics['age'] = 18# 然后进行添加值
print(dics)
f2 = open('test','wb')# 在把最新的这个字典序列化文件中
dics = pickle.dump(dics,f2)

f3 = open('test','rb')
dics = pickle.load(f3)# 最后在反序列回来进行打印这个字典
print(dics)
[code]# 如下是shelve模块的操作
import shelve
f = shelve.open('test')
f['name'] = "makes"
print(f['name'])    # 添加后可以通过键直接查看,
f['age'] = 20
print(f['age'])     # 添加后就能直接查看,不在需要多次的dump和load了

1、键值对中,键必须是字符串类型,值可以是任何数据类型,没有要求

2、其实shelve这个模块就是一个open和字典的操作

3、除了不能直接查看字典中所的内容,字典的其他方法都具备,.keys()、.velues()、.items()等可以通过for循环查看

4、shelve模块有个坑需要注意的就是文件回写的时候会出现写不成功,只需要在open这函数的地方写一个writeback=True 这就是回写。还有就是只读模式下添加键值对,也会存在这样的情况。

 

[code]import shelve
f = shelve.open('test') # 创建了一个文件
f['name'] = 'alex'   # 字典的增加
f.close()

f1 = shelve.open('test')   # writeback=True
f1['name'] = 'mask'
f1.close()

f = shelve.open('test')
print(f['name'])  # 结果是mask,正确的应该是alex,回写不成功
# 该情况下回写不成功,不会报错,避免方案是open的地方加# writeback=True

f1 = shelve.open('test',flag='r')  # 只读
f1['age'] = 18
f1.close()        # 只读模式下修改文件也是同样的情况

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: