咱们把变量从内存中变成可存储或传输的过程称之为序列化,序列化以后就能够吧序列化后的内容写入磁盘,或者经过网络传输到别的机器上。python
反过来,吧变量内容从序列化的对象从新读取到内存里称之为返序列化。数据库
python 提供了pickle模块来实现序列化编程
把一个对象序列化并写入文件:json
import pickle d = dict(name='bob',age=20) pickle.dumps(d)
>>>b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x03\x00\x00\x00bobq\x02X\x03\x00\x00\x00ageq\x03K\x14u.'
pickle.dumps()方法把人与i任意对象序列化成一个bytes,而后,就能够把这个bytes写文件,或者用列一个方法pickle.dump()直接把对象序列化后写入一个file-like object:缓存
f = open('xxx','wb') pickle.dump(d,f) f.close()
当咱们要把对象从磁盘督导内存时,能够先把内容读取到一个bytes,而后在用pickle.loads()方法反序列化出对象,也能够直接使用pickle.load()方法直接从一个file-like Object中反序列化出对象网络
f = open('xxx','rb') pickle.load(f) f.close
若要反序列化多个数据,则须要屡次使用pickle.load()方法编程语言
反序列化获得的变量和原来的变量时彻底不想干的对对象,他们只是呢容相同而已this
若是咱们用pickle序列化了许多不一样类型的对象,当咱们想要反序列化摸一个类型时就会显得很是麻烦,但同时咱们又不但愿使用数据库那么重量级的东西去存储一丢丢数据时,编码
不放但是尝试一下,python给咱们提供的shelve这个模块,shelf也是使用key来访问的,使用起来和字典相似。shelve其实用anybdm去建立DB而且管理持久化对象的。spa
建立一个新的shelf
直接用shelve.open()方法就能够建立了
import shelve s = shelve.open('db') try: s['keys'] = {'int': 10, 'float':9.5, 'string':'Sample data'} finally: s.close()
若是想要再次访问这个shelf,只须要再次使用shelve.open()方法打开这个文件,而后咱们i就能够像使用字典同样来使用这个shelf了。
import shelve s = shelve.open('db') try: info = s['keys'] finally: s.close() print(info)
dbm这个模块有个限制,它不支持多个应用在同一时间对同一个DB进行写操做,所用当咱们知道咱们的应用只是进行读操做,咱们可让shelve经过只读方式打开DB:
import shelve a = shelve.open('db', flag='r') try: info = a['key'] finally: a.close()
当咱们的程序试图去修改一个以只读方式打开的DB时,将会抛出一个异常,异常类型取决于anybdm这个模块在建立DB所选用的DB
写回(Write-back)
因为shelve在默认状况下是不会记录持久化对象的任何修改的,因此咱们在shelve.open()时候须要修改默认参数,佛则对象不会保存
def open(filename,flag='c', protocol=None, writeback=False) import shelve s = shelve.open('test_shelf.db') try: print s['key1'] s['key1']['new_value'] = 'this was not here before' finally: s.close() s = shelve.open('test_shelf.db', writeback=True) try: print s['key1'] finally: s.close()
上面这个例子中,因为一开始咱们使用了缺省参数shelve.open()了,所以第6行修改的值即便咱们s.close()也不会被保存。
因此当咱们试图让shelve去自动捕获对象的变化时,咱们应该打开shelf的时候将writeback设置为True。当咱们将Writeback这个flag设置为True之后,shelf将会将全部从DB中读取的对象放到一个内存缓存中,当咱们close()打开的shelf的时候,缓存中的对象会被从新写入DB
import shelve s = shelve.open('db',writeback=True) try: print(s['key1']) s['key1']['new_value'] = 'this was not here before' print(s['key1']) finally: s.close() s = shelve.open('db',writeback=True) try: print(s['key1']) finally: s.close()
writeback方式有优势也有缺点。优势就是减小了咱们出错的几率,而且让对象的持久化对用户更加透明了;但这种方式斌不是全部的状况下都须要的,首先,使用writeback之后,shelf在open()时候会增长额外的内存消耗,而且DB在close()的时候会将缓存中的每个对象都写入到DB,这也会带来额外的等待时间,由于shelve没有办法知道缓存中哪些对象修改了,所以全部的对象都会被写入。
$ python shelve_create.py $ python shelve_writeback.py {'int': 10, 'float': 9.5, 'string': 'Sample data'} {'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'} {'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'}
不论是pickle仍是shelve的问题和全部其余编程语言特有的序列化问题同样,就是他只能用于python。
JSON
若是咱们要在不一样的编程语言之间传递对象,就必须把对象序列化为标准格式,好比XML,但更好的方法是序列化为JSON,由于JSON表示出来就是一个字符串,能够被全部语言读取,也能够方便地存储到磁盘或者经过网络传输。JSON不只是标准格式,而且比XML更快,并且能够直接在Web页面中读取,很是方便。
JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应以下:
JSON类型 | Python类型 |
{} | dict |
[] | list |
"string" | str |
1234.56 | int或float |
true/false | True/False |
null | None |
Python内置的json
模块提供了很是完善的Python对象到JSON格式的转换。咱们先看看如何把Python对象变成一个JSON:
import ison d = dict(name='bob',age=12) json.dumps(d) '{"name": "bob", "age": 12}'
dumps()
方法返回一个str
,内容就是标准的JSON。相似的,dump()
方法能够直接把JSON写入一个file-like Object
。
要把JSON反序列化为python对象,用loads()或者对应的load()方法,前者把JSON的字符串反序列化,后者从file-like Object读取字符串再反序列化:
json_str = '{"age": 20, "score": 88, "name": "Bob"}' json.loads(json_str) {'age': 20, 'score': 88, 'name': 'Bob'}
因为JSON标准规定JSON编码是UTF-8,因此咱们老是能正确地在Python的str
与JSON的字符串之间转换。