序列化:將變量從內(nèi)存中變?yōu)榭纱鎯?chǔ)或傳輸?shù)倪^程哪轿;
反序列化:把序列化的內(nèi)容重新讀到內(nèi)存;
pickle
python 自帶 pickle 模塊用來實(shí)現(xiàn)序列化與反序列化道伟;
寫文件
pickle.dumps() 可以把對(duì)象轉(zhuǎn)換為 bytes帚豪,然后就可以把這個(gè) bytes 寫入文件了(它會(huì)自動(dòng)創(chuàng)建文件,不需要額外手動(dòng)創(chuàng)建):
>>> import pickle
>>> d = dict(name='majun', age=27)
>>> pickle.dumps(d)
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x05\x00\x00\x00majunq\x02X\x03\x00\x00\x00ageq\x03K\x1bu.'
pickle.dump() 方法可以直接把對(duì)象序列化后寫入文件:
>>> f = open('dump.txt','wb')
>>> pickle.dump(d,f)
>>> f.close()
結(jié)果:
讀文件
pickle.load() 方法
>>> f = open('dump.txt','rb')
>>> pickle.load(f)
{'name': 'majun', 'age': 27}
>>> f.close()
但是 pickle 處理的數(shù)據(jù)只能用于 python 空另,且不同版本的數(shù)據(jù)也不兼容。因此蹋砚,pickle 只能處理一些不重要的數(shù)據(jù)扼菠。如果想要保存交互式數(shù)據(jù),就只能用 json 模塊了都弹。
json
如果需要在不同語言之間傳遞對(duì)象娇豫,就需要把對(duì)象序列化為標(biāo)準(zhǔn)格式匙姜,比如 XML畅厢。但最好序列化為 JSON 格式,因?yàn)?JSON 表示出來就是字符串氮昧,可以被所有語言讀取框杜,也可以方便讀取和網(wǎng)絡(luò)傳輸。JSON 不僅是標(biāo)準(zhǔn)格式袖肥,而且比 XML 更快咪辱。
python 內(nèi)置模塊 json 能夠?qū)崿F(xiàn) python 對(duì)象與 json 對(duì)象的轉(zhuǎn)換:
json.dumps() 轉(zhuǎn)換為 json 對(duì)象
>>> import json
>>> d = dict(name="majun", age=27)
>>> json.dumps(d)
'{"name": "majun", "age": 27}'
如果對(duì)格式有要求且正確處理中文,可設(shè)置相關(guān)參數(shù):
>>> with open('test.txt', 'w') as f:
... d.update(dict(sex='男'))
... data = json.dumps(d, indent = 2, ensure_ascii = False)
... f.write(data)
json.loads() 轉(zhuǎn)換為 python 對(duì)象
>>> a = json.dumps(d)
>>> json.loads(a)
{'name': 'majun', 'age': 27}
>>> c = '{"name":"majun", "age": 27}'
>>> json.loads(c)
{'name': 'majun', 'age': 27}
由于 JSON 標(biāo)準(zhǔn)規(guī)定 JSON 編碼采用 UTF-8椎组,所以我們能正確的進(jìn)行 python 與 json 數(shù)據(jù)之間的轉(zhuǎn)換油狂;
json.dump() 、json.load() 方法實(shí)現(xiàn)文件的直接寫入/讀取
>>> f = open('dump.txt','w')
>>> json.dump(d, f)
>>> f.close()
>>> f = open('dump.txt','r')
>>> json.load(f)
{'name': 'majun', 'age': 27}
注意:
- dumps()、loads() 只是將 python 數(shù)據(jù)與 json 數(shù)據(jù)進(jìn)行轉(zhuǎn)換专筷;
- dump()弱贼、load() 可以直接進(jìn)行轉(zhuǎn)換,然后保存 / 提取 文檔磷蛹;
>>> f = open('dump.txt','r')
>>> a = f.read()
>>> a
'{"name": "majun", "age": 27}'
>>> json.loads(a)
{'name': 'majun', 'age': 27}
- 寫文件默認(rèn)會(huì)清空已有文件吮旅,然后寫入。如果將第二個(gè)參數(shù)替換為 "a"味咳,那么可以在就內(nèi)容后面追加新內(nèi)容庇勃。
JSON進(jìn)階
面向?qū)ο缶幊涛覀円话闶褂?類class 存儲(chǔ)數(shù)據(jù),那么我們?cè)趺幢4孢@類數(shù)據(jù)呢槽驶?
簡(jiǎn)單說就是屬性與字典的相互轉(zhuǎn)換:
保存到文件的時(shí)候责嚷,轉(zhuǎn)換成字典形式。取出來的時(shí)候捺檬,轉(zhuǎn)換成類屬性形式再层;
import json
def save(data, path):
d = json.dumps(data, indent=2, ensure_ascii=False)
with open(path, 'w') as f:
f.write(d)
def load(path):
with open(path, 'r') as f:
data = f.read()
return json.loads(data)
class person(object):
def __init__(self, form):
self.name = form.get('name', '')
self.sex = form.get('sex', '')
self.age = form.get('age', 0)
@classmethod
def new(cls, form, **kwargs):
p = cls(form)
for k, v in kwargs.items():
setattr(p, k, v)
p.save()
return p
@classmethod
def new_from_dict(cls, dic):
p = cls({})
for k, v in dic.items():
setattr(p, k, v)
return p
@classmethod
def all(cls):
path = cls.path()
persons = load(path)
ps = [ cls.new_from_dict(p) for p in persons]
return ps
@classmethod
def path(cls):
name = cls.__class__.__name__
path = '{}.text'.format(name)
return path
def save(self):
ps = self.all()
ps = ps.append(self)
data = [p.__dict__ for p in ps]
path = self.path()
save(data, path)