初识Json&pickle函数序列化附加shelve模块
通过例子逐步解释序列化
例子1
1 info={
2 'name':'jack',
3 'age':20
4 }
5 f=open('test.text','w')
6 f.write(info)
因为是字典数据类型,不能写入硬盘,运行出错
例子2
1 info={
2 'name':'jack',
3 'age':20
4 }
5 f=open('test.text','w')
6 f.write(str(info)) #把字典转成字符串
把字典转成字符串数据类型,能写入硬盘,数据从内存写入到硬盘上叫做序列化
例子3
1 f=open('test.text','r')
2 data=f.read()
3 print(data) #>> {'name': 'jack', 'age': 20}
从硬盘读出数据,是字符串数据类型
例子4
1 f=open('test.text','r')
2 data=f.read()
3 print(data['age'])
以字典方式操作,出错,因为文件里存储的是字符串
例子5
1 f=open('test.text','r')
2 data=eval(f.read())
3 print(data['age'])
用eval()函数将字符串转成字典读出,从硬盘读出数据到内存也叫反序列化
以上序列化和反序列化实现了把内存的数据对象存储到硬盘上,再读回来,相当于虚拟机挂起,又重新读取运行
以上的序列化和反序列化都是简单、不标准的
如要通用、标准的序列化和反序列化,需要用到Json模块里的dumps()和loads()
例子6
1 import json
2 info={
3 'name':'jack',
4 'age':20
5 }
6 f=open('test.text','w')
7 #print(json.dumps(info)) #转成字符串输出
8 f.write(json.dumps(info)) #转成字符串存储到文件
序列化
例子7
1 import json
2 f=open('test.text','r')
3 data=json.loads(f.read()) #反序列化
4 print(data['age']) #>>20
json只能处理简单的数据类型,像列表、字典、字符串等,因为各语言的对象、类等都不相同
json是所有编程语言都通用的,所有语言都支持json。
json主要的作用是不同语言进行数据交互,已经成为主流的不同平台的数据交换,逐步取代XML
json可以dumps多次,但只能loads一次,规定要求dumps一次,loads一次
例子8
1 import json
2 def sayhi(name):
3 print('hello',name)
4
5 info={
6 'name':'jack',
7 'age':20,
8 'func':sayhi #sayhi()函数的内存地址
9 }
10 f=open('test.text','w')
11 f.write(json.dumps(info)) #>>TypeError: Object of type 'function' is not JSON serializable
12 #“函数”的对象不是JSON序列化类型
13 f.close()
Json不能处理复杂的,带有函数的数据交互
这时需要用到pickle模块,pickle用法与Json完全一样,只不过换个名字而已
例子9
1 import pickle
2 #序列化
3 def sayhi(name):
4 print('hello',name)
5
6 info={
7 'name':'jack',
8 'age':20,
9 'func':sayhi #sayhi()函数的内存地址
10 }
11 f=open('test.text','wb')
12 #print(pickle.dumps(info)) #>>b'\x80\x03}q\x00(X\x04\x00.....输出二进制所以要由'w'改'wb'
13 f.write(pickle.dumps(info)) #可以写入pickle专门的字符存储在文件
14 #简写:pickle.dump(info,f)
15 f.close()
反序列化
1 import pickle
2 f=open('test.text','rb') #注意'rb'
3 data=pickle.loads(f.read()) #反序列化
4 print(data) >>AttributeError: Can't get attribute 'sayhi' on <module '__main__' from 'D:/T..
5
出错,说明sayhi()函数的内存地址随着序列化文件释放了,对象就没找到,如要序列化就把sayhi()拷贝过来
改进如下:例子10
1 import pickle
2 def sayhi(name):
3 print('hello',name) #反序列化时只要函数名一样,可以更改函数内容
4
5 f=open('test.text','rb') #注意'rb'
6 data=pickle.loads(f.read()) #反序列化
7 #简写:data=pickle.load(f)
8 print(data) #>>{'name': 'jack', 'age': 20, 'func': <function sayhi at 0x00000000003D3EA0>}
9 print(data['func']('Alice')) #>>hello Alice
10 f.close()
反序列化成功
pickle 最终实现了函数的序列化,但pickle只能在本语言内使用,java是不认识pickle数据类型的
shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式
1 import shelve
2 import datetime
3
4 #写入
5 d = shelve.open('shelve_test') # 打开一个文件
6 info={'age:22','job:it'}
7 name = ["alex", "rain", "test"]
8 d["name"] = name # 持久化列表
9 d["info"] = info # 持久化类
10 d["date"] = datetime.datetime.now()
11
12 d.close()
1 import shelve
2 import datetime
3
4 #读出
5 d=shelve.open('shelve_test')
6 print(d.get('name'))
7 print(d.get('info'))
8 print(d.get('date'))
9
10 d.close()