Python——Serialization 总结

忘记从谁的主页记的笔记了,Sorry

一、pickle Module

通过将对象序列化可以将其以字节(byte)的形式存储在变量或文件中,可以保存当时对象的状态,实现其生命周期的延长,并且需要时可以再次将这个对象读取出来。

1、将对象存在变量中,返回存入的字节(pickle.dumps(obj) , pickle.loads(byte_obj))

<prickling>

>>>import pickle

>>>d={'name':'Bob','age':6}

>>>byte_d= pickle.dumps(dic)   # now pickling,此时,数据以字节的形式保存在byte_d变量中,需要使用的时候用loads函数unpickling还原出来

>>>print(byte_d)

b'\............\x00\x80\.................'  #打印出来,可见是字节的形式

<unprickling>

>>>import pickle

>>>obj=pickle.loads(byte_b)

>>>print(obj)

{'name':'Bob','age':6}

 

2、将对象存在文件中,返回存入的字节(pickle.dump(obj,f) , pickle.load(f))

也可以将对象存入file-like object中,使得对象持久化,使用的是dump和load函数(没有s);由于pickle写入的是二进制数据,所以打开方式要以wb和rb的模式

<pickling>

>>>import pickle

>>>with open('am.txt','wb') as f:    #在当前工作目录notepad下新建了一个可写入文件am.txt

    d={'name':'Bob','age':6}

    pickle.dump(d,f)

#或者也可以这样:

>>>d={'name':'Bob','age':6}

>>>f=open('am.txt','wb')

>>>pickle.dump(d,f)

>>>f.close()    #别忘了

>>>print(f)

<_io.BufferedReader name='mm.txt'>

<unpickling>

>>>with open('am.txt','rb') as f:

    ff=pickle.load(f)    #byte to dict

    print(ff)

...

{'name':'Bob','age':6}

 

3、序列化用户自定义对象: pickle当然也能写入,不仅可以写入类本身,也可以写入它的实例

>>>class Student():

  def __init__(self,name,age,behave):

    self.name=name

    self.age=age

    self.behave=behave

  def behavior(self):

    print('%s behaves %s', % (self.name, self.behave))

#将实例存储在变量中,当然也能存在file-like Object中

>>>bob = Student('Bobby',7,'Good')

>>>import pickle

>>>byte_bob = pickle.dumps(bob)    #将转化为字节后的实例bob存在变量byte_bob中

>>>byte_bob

b'\x80\x03c__main__\....................\'

#unpickling还原

>>>bob=pickle.loads(byte_bob)

>>>bob.name

'Bobby'

>>>bob.behavior()

Bobby behaves Good

 

二、 json Module

pickle可以很方便的序列化所有对象,不过json作为更为标准的格式,具有更好的可读性(pickle是二进制数据)和跨平台性,json使用的四个函数名和pickle一致

(一)序列化为字符串

>>>import json

#序列化,dict to str

>>>d={'name':'Bob','age':6}

>>>d_str = json.dumps(d)

<class 'str'>{"name":"Bob","age":6}

#反序列化,还原,str to dict

>>>d_obj=json.loads(d_str)

<class 'dict'>{'name':'Bob','age':6}

#可见,dumps函数将对象转换成字符串,loads函数又将其恢复为字典

(二)也可以存在file-like Object中

>>>d={'name':'Bob','age':6}

>>>import json

>>>with open('mm.txt','w') as f:    #由于是变成str,所以为w模式

    json.dump(d,f)    

#反序列化还原

>>>with open('mm.txt','r') as f:

    print(json.load(f))

 

(三)存储自定义对象——json中,对于用户自定义的类和类实例,如果直接序列化会报错

>>>class Student():

    def __init__(self,name,age,behave):

      self.name=name

      self.age=age

      self.behave=behave

    def behavior(self):

      print('%s hehaves %s' % (self.name,self.behave))

>>>bob=Student('Bobby',6,'Good')

>>>import json

>>>with open('am.txt','w') as f:

    json.dump(bob,f)

TypeError:object of type 'Student' is not Json Serializable

错误的原因是Student对象不是一个可序列化为JSON的对象。

dumps()方法的参数除了第一个必须的obj参数外,还提供了很多可选参数,这些可选参数就是让我们来定制JSON序列化。前面的代码之所以无法把Student类实例序列化为JSON,是因为默认情况下,dumps()方法不知道如何将Student实例变为一个JSON的dict对象。

可选参数default就是把任意一个对象变成一个可序列为JSON的对象,我们只需要为Student专门写一个转换函数,将类实例转换为dict,再把函数作为参数传进去即可:

def stu2Dict(stu):

  return {'name': stu.name, 'age':stu.age, 'behave':stu.behave}   # 这样就返回一个字典了

>>>print(json.dumps(bob, default=stu2Dict))

{'name':'Bobby','age':6,'behave':'Good'}     # 实例bob变成了一个字典

同常class实例有一个__dict__属性,它就是一个dict,用来存储实例变量,可以偷个懒,把任意class的实例变为dict:

>>>print(json.dumps(bob,default=lambda obj: obj.__dict__))

同时,在读取的时候load出来的是一个字典,需要再转化为类实例,同样需要一个object_hook参数,该参数接受一个函数,该函数用于将字典转化为对象:

>>>def dict2Stu(d):

    return Student(d['name'],d['age'],d['behave'])   #由字典变为了实例对象

完整程序如下:

>>>import json

>>>with open('am.txt','w') as f:

     json.dump(bob,f,default=lamba obj: obj.__dict__)

>>>def dict2Stu(d):

    return Student(d['name'],d['age'],d['behave'])

>>>with open('am.txt','r') as f:

    bob = json.load(f,object_hook(dict2Stu))

    print(bob.name,bob.age.bob.behave)

    bob.behavior()

 

 

   

 

 

 

 

 

 

    

 

posted @ 2018-04-11 13:50  lyuannie  阅读(1235)  评论(0编辑  收藏  举报