1、对象持久化
1、1:对象持久化概述: 序列化:就是将我们目前的内存运行进度结果存储到一个媒介或者是硬盘上面!这就是序列化!
将存储的一些数据反序列化到内存中! 还原以前的状态!这就是反序列化!
开发中我们常见的序列化和持久化的技术有哪些呢??
1、对于文本文件,就是以扁平文件来持久化。还有python中的pickle技术,还有shelve、数据库、ORM。
本章中只讲述在python中扁平文件、pickle、shelve,怎么样序列化持久保存对象以及对文件的反序列化~~
具体案例:
1、扁平文件:就是我们说的文本文件。如果想要文本文件保存我们计算的对象等之类的数据话~,因为本身文本文件就是保存文本的!所以保存的对象啊~这些会以文本的形式存储(也就是纯文字),我们再把他反序列化载入到内存中的时候,我们这里面有一个类型还原的过程,所以步骤稍微多一点!
1、使用文本文件存储具有类型的对象(不推荐) :
第一步、将成绩列表写入到文本文件中 :
#coding=gbk
"""以文本化的文件来存储持久化的对象"""
scores = [88,99,77,55]
#将信息定义到一个文本文件中,我们写一个函数
def writ_scores():
with open('data_list.txt','w',encoding='utf-8') as f:
f.write(str(scores))
print('文件写入完成!!')
writ_scores()
在这类的当前目录下就会出现一个data_list.txt的文件。这个文件中在写入的时候形式上是一个数组,但是本质上是一个文本文件!
第二步:读取该文本、并且还原其类型!
#coding=gbk
"""以文本化的文件来存储持久化的对象"""
scores = [88,99,77,55]
#将信息定义到一个文本文件中,我们写一个函数
def writ_scores():
with open('data_list.txt','w',encoding='utf-8') as f:
f.write(str(scores))
print('文件写入完成!!')
#将文本文件读取到内存中,并且还原以前的数据类型
def read_scores():
with open('data_list.txt','r',encoding='utf-8') as f:
lst = f.read() #记住这一会读取的是文本文件类型的! 并非list类型
lst = eval(lst)
lst[0] = 99
print(lst)
if __name__ == '__main__':
read_scores()
在这里面,python给我们内置了一个函数! 叫做eval() 。 这个函数的会把字符串中符合python表达式的东西计算出来。在上面代码汇总,用到eval()函数以后,然后对列表的第一个值进行了修改!并且成功,说明在读取的时候就是读取过来的列表类型的数据。
2、使用pickle存储具有类型的对象 (推荐:但是一个对象一个文件维护会很麻烦):
pickle是python给我们自带的一个模块。它帮我们封装了一系列的方法和接口,他可以轻易的将我们的内存中原有的python类型的对象序列化为字符串或者本地的一个文件。 案例:
>>>import pickle
>>>person = {'name':'Tom','age':20}
>>>person
{'name': 'Tom', 'age': 20}
>>>p = pickle.dumps(person)
>>>p
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x03\x00\x00\x00Tomq\x02X\x03\x00\x00\x00ageq\x03K\x14u.'
>>>ps = pickle.loads(p)
>>>ps
{'name': 'Tom', 'age': 20}
>>>type(ps)
<class 'dict'>
>>>type(p)
<class 'bytes'>
直接调用pickle模块下面的dumps()函数和loads()函数,这个s代表的是字符串。并不是代表负数的意思。!这函数可以将你的类型转化为byte存储。异常方便。 dumps(obj) : 将对象序列化为字符串。loads(s):从字符串反序列化对象。
3、使用pickle模块将我们有类型特征序列化保存到文件中,在从文件中反序列化读取 : 文件是二进制文件。
>>>person = {'name':'Tomm','age':20}
>>>person
{'age': 20, 'name': 'Tomm'}
>>>import pickle
>>>pickle.dump(person,open('pickle_db','wb'))
>>>p = pickle.load(open('pickle_db','rb'))
>>>p
>>>{'age': 20, 'name': 'Tomm'}
>>>type(p)
<class 'dict'>
这里使用了dump和load
pickle是存在缺陷的! 如果一个对象存在一个文件中!问题不大!那么如果将多个对象存到一个文件中,由于在反序列的时候是将整个文件中的对象反序列化,所以在过滤我们想要的对象的时候是挺麻烦的!如果将不同的对象存在不同的文件中是可以解决这样的问题,但是这样维护起来会相当的麻烦的!这样我们使用python中的shelve会更一步的简化!
4、使用shelve将我们的多个对象可以存储到一个文件里面。给不同的对象增加不同的键值!跟我们的字典表很相似。看代码
#coding=gbk
import shelve
#定义两个对象
score = [99,88,77]
student = {'name':'Tom','age':20}
#首先准备一个数据库文件,调用shelve模块下的open方法
db = shelve.open('shelve_student')
#将student这个字典表对象存储进来,并且赋予一个键是’s‘的!
db['s'] = student
#将score这个列表的对象存储进来,然后赋予一个键为’sc‘!
db['sc'] = score
#查看该数据库文件中存储了多少个的文件对象
print(len(db)) # output:2
#查看该文件中学生的对象是什么!
tmpStudent = db['s']
print(tmpStudent)
#查看该文件中成绩的对象!
tmpScore = db['sc']
print(tmpScore)
#删除文件中存储的对象,用全局函数
del(db['s'])
print(len(db)) #ouutput : 1
上面的例子就是我们使用shelve进行的一系列的操作!那么我们自己创建的实例能够被存放或者是读取嘛?可以的!看代码!
#coding=gbk
import shelve
class student():
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return self.name
#将我们创建的实例写入到一个文件中
def write_student():
"""首先创建我们的实例"""
s = student('tom',20)
db = shelve.open('shelve_student_db')
db['s'] = s #将我们自己创建的S对象保存到db文件中,以s为键保存
db.close()
#读取我们写入的文件
def read_student():
db = shelve.open('shelve_student_db')
temp_student = db['s']
print(temp_student)
print(temp_student.name)
print(temp_student.age)
if __name__ == '__main__':
read_student()