Python持久化主要有2种方式:
外部系统通信:JSON,在系统外部主要采用JSON方式通信;
内部系统通信:Pickle和Marshal,pickle用于持久化Python对象,Marshal用于持久化pyc文件,实际中pyc文件可能格式发生变化,这样Marshal持久化就可能会失败。而Pickle为Python对象持久化,我们则可以通过对象的定义、持久化控制来实现对象的版本差异性。我们这里主要讨论方式2。
Pickle模块主要提供了2个方法来进行持久化:序列化dump和反序列号load,分别对应于序列化文件或字符串。
import pickle
class A(object):
def __init__(self):
self.level = 0
self.lives = 4
if __name__ =="__main__":
s = A()
serialized = pickle.dumps(s)
after = pickle.loads(serialized)
print('after:%s\n,dict:%s'%(serialized,after.__dict__))
当类A发生变化(增加或修改成员)时,我们可以在类A中设置版本号,并在序列化前后设置不同的版本信息。
import pickle
import copyreg
class A(object):
def __init__(self,point = 4,version = 1):
self.level = 0
self.lives = 4
self.point = point
self.version = version
def pick_A(obj):
kwargs = obj.__dict__
return unpickle_A,(kwargs,)
def unpickle_A(kwargs):
version = kwargs.pop('version',1)
if version == 1:
kwargs.pop('point')
return A(kwargs)
if __name__ == "__main__":
copyreg.pickle(A,pick_A)
s= A(version = 3)
serialized = pickle.dumps(s)
print("serialized:%s" % (serialized))
after = pickle.loads(serialized)
print('after version 3:%s\n,dict:%s'%(serialized,after.__dict__))
f= open('obja.txt','wb')
a= A()
pickle.dump(a,f)
f= open('obja.txt','rb')
after = pickle.load(f)
print('afterversion 1:%s\n,dict:%s'%(serialized,after.__dict__))
marshal则只能针对程序代码或系统内置类型进行持久化,对于用户自定义类型则无法实现持久化,且持久化依赖于版本信息,可以在持久化信息中加入版本信息以实现版本校验。
code = """
class A(object):
def__init__(self,point = 4,version = 1):
self.level= 0
self.lives= 4
self.point= point
self.version= version
"""
str = marshal.dumps(compile(code,'','exec'))
b = marshal.loads(str)
print('aftermarshal:%s\n,type:%s,code:%s'%(str,type(b),b))
dict = {"1":1,
"2":2}
str = marshal.dumps(dict)
b = marshal.loads(str)
print('aftermarshal:%s\n,type:%s,code:%s'%(str,type(b),b))
领取专属 10元无门槛券
私享最新 技术干货