1) 将内存中的对象转换成为文本流:
import pickle
# define class
class Contact(object):
def __init__(self, uid, name, age):
self.uid = uid
self.age = age
self.name = name
c = Contact(1001,'aaa',25)
ps = pickle.dumps(c) #转换成字符串
c_copy = pickle.loads(ps) #转换成对象
使用pickle.dumps()方法可以将对象c转换成了字符串
当然,我们也可以使用pickle.dump()的方法,将上面两部合二为一:
import pickle
class Contact(object):
def __init__(self, uid, name, age):
self.uid = uid
self.age = age
self.name = name
c = Contact(1005)with open('./tmp.data', 'w') as f: 对象c存储在文件ymp.data
2) 重建对象
首先,我们要从文本中读出文本,存储到字符串 (文本文件的输入输出)。然后使用pickle.loads(str)的方法,将字符串转换成为对象。要记得,此时我们的程序中必须已经有了该对象的类定义。
此外,我们也可以使用pickle.load()的方法,将上面步骤合并:
import pickle
class Contact(object):
def __init__(self, uid, name, age):
self.uid = uid
self.age = age
self.name = name
fn =
'
./tmp.data
'
with open(fn,
'
r
'
) as f: summer =
pickle.load(f)
cPickle包的功能和用法与pickle包几乎完全相同 (其存在差别的地方实际上很少用到),不同在于cPickle是基于c语言编写的,速度是pickle包的1000倍。对于上面的例子,如果想使用cPickle包,我们都可以将import语句改为:
import cPickle as pickle
就不需要再做任何改动了。
下面时存储数据的小实例:
contact.py
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import copy
import json
import base
__all__ = ['Contact']
class Contact(base.Base):
'''联系人'''
DEBUG = True
def __init__(self, **kwargs):
self.init(**kwargs)
def init(self, **kwargs):
self.uid = kwargs.pop('uid', 0)
self.name = kwargs.pop('name', '')
self.age = kwargs.pop('age', 0)
self.addr = kwargs.pop('addr','')
self.phone = kwargs.pop('phone', '')
self.ext = json.loads(kwargs.pop('ext', '{}'))
def __str__(self):
return "id:%s,uid:%s,name:%s,age:%s,%s"%(id(self), self.uid,self.name, self.age,','.join(['%s:%s'%(k,v) for k, v in self.ext.iteritems()]))
def __getattr__(self, k):
if Contact.DEBUG:
print 'in Contact __getattr__ %s'%k
return self.ext.get(k)
def get_key(self):
return self.uid
def changed(self):
if getattr(self, 'manager'):
self.manager.changed = True
def set_age(self, age):
assert type(age)==int, 'age must be interge'
self.age = age
self.changed()
def set_uid(self, uid):
assert type(uid)==int, 'uid must be interge'
self.uid = uid
self.changed()
def set_name(self, name):
assert type(name)==str, 'name must be string'
self.name = name
self.changed()
def load(self, **kwargs):
return self.init(**kwargs)
def save(self):
m = self.__dict__.pop('manager', None)
data = copy.deepcopy(self.__dict__)
self.manager = m
data['ext'] = json.dumps(data['ext'])
return data
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import os
import sys
import cPickle
class Loader(object):
'''cPickle loader'''
def __init__(self, filename=None):
self.filename = filename
def load(self, filename=None):
data = []
filename = filename or self.filename
try:
with open(filename or self.filename, 'r') as fd:
data = cPickle.load(fd)
except:
print 'load data failed'
return data
def save(self, data, filename=None):
assert (filename or self.filename), 'give a filename to save data'
try:
with open(filename or self.filename, 'w') as fd:
cPickle.dump(data, fd)
except:
return False
return True
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Manager(object):
'''联系人管理类'''
def __init__(self, memclass, loader, condition=None):
''''''
self.changed = False
self.loader = loader
self.memclass = memclass
self.member = self.loader.load(condition) if condition else {}
def add_mem(self, memobj):
okey = memobj.get_key()
if okey in self.member:
return False
memobj.manager = self
self.changed = True
self.member[okey] = memobj
return True
def del_mem(self, memobj=None, mkey=None):
obj = None
if memobj:
obj = self.member.pop(memobj.get_key(), None)
if mkey:
obj = self.member.pop(mkey, None)
if obj:
obj.manager = None
return obj
def find_mem(self, mkey):
return self.member.get(mkey, None)
def load(self, condition=None):
assert not self.changed, "the member is not null, you should save first"
data = self.loader.load(condition)
for e in data:
if isinstance(e, self.memclass):
memobj = e
else:
memobj = self.memclass(**e)
memobj.manager = self
self.member[memobj.get_key()] = memobj
def save(self):
if self.changed:
data = []
for _, memobj in self.member.iteritems():
data.append(memobj.save())
self.loader.save(data)
self.changed = False
def display(self):
for _, m in self.member.iteritems():
print m
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import contact
import loader
import manager
def main():
tmp_loader = loader.Loader('./tmp.data')
tmp_manager = manager.Manager(contact.Contact, tmp_loader)
tmp_contact = contact.Contact()
tmp_contact.set_uid(1001)
tmp_contact.set_age(25)
tmp_contact.set_name('nnn')
tmp_manager.add_mem(tmp_contact)
tmp_manager.save()
if __name__=='__main__':
main()