本文最后更新于:2019 , 八月 19日 星期一, 5:12 下午

简介

序列化:将原本的字典,列表等内容转换成一个字符串的过程
反序列化:从字符串转换成数据类型的过程

序列化的目的

  • 以某种存储形式使自定义对象持久化
  • 将对象从一个地方传递到另一个地方
  • 使程序更具维护性

常用模块

  • json

    通用的序列化格式
    只有很少的一部分数据类型能够通过json转换成字符串

  • pickle

    所有的python中的数据类型都可转化成字符串形式
    pickle序列化的内容只有python能理解
    且部分反序列化依赖代码

  • shelve

    序列化句柄
    使用句柄直接操作,非常方便


json

可以转换的数据类型:数字,字符串,列表,字典,元组

Json模块提供了四个功能

  • dumps – 序列化方法
  • loads – 反序列化方法
  • dump – 序列化,并写入文件
  • load – 只接收文件文件描述符,完成读取文件和反序列化

dumps 和 loads

dumps格式

def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,allow_nan=True, cls=None, indent=None, separators=None,default=None, sort_keys=False, **kw):pass

参数说明:
skipkeys:默认值时False,如果dict的keys内的数据不是python的基本类型,设置为False时,就会报TypeError的错误。此时设置成True,则会跳过这类key

ensure_ascii:当它为True的时候,所有非ASCII码字符显示为\uXXXX序列,只需在dump时将ensure_ascii设置为False即可

indent:应该是一个非负的整型,如果是0就是顶格分行显示,如果为空就是一行最紧凑显示,否则会换行且按照indent的数值显示前面的空白分行显示

separators:分隔符,实际上是(item_separator, dict_separator)的一个元组,默认的就是(‘,’,’:’);这表示dictionary内keys之间用“,”隔开,而KEY和value之间用“:”隔开

sort_keys:将数据根据keys的值进行排序
# 序列化与反序列化
import json

dict = {'k1':'v1'}
x = json.dumps(dict)

print(json.loads(x))

dumps序列化时对中文默认使用的ascii编码,想输出真正的中文需要指定ensure_ascii=False

dump 和 load

Tips:每次读取和写入最好都是一条一条的

import json

f = open('json_file','w')
dic = {'k1':'v1','k2':'v2','k3':'v3'}
json.dump(dic,f) #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件 f.close()

f = open('json_file')
dic2 = json.load(f) #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
f.close() print(type(dic2),dic2)

利用dumps 和 loads写入和读取

import json

# 写入
l = [{'k':'111'},{'k2':'22'},{'k3':'22'}]
f = open('pass.txt','w',encoding='utf-8')
for dic in l:
    str_dic = json.dumps(dic)
    f.write(str_dic+'\n')
f.close()

# 读取
l = []
for line in f:
    dic = json.loads(line.strip())
    l.append(dic)
l.close

pickle

json:用于字符串和python数据类型间进行转换
pickle:用于python特有的类型和python的数据类型间进行转换

pickle模块提供了四个功能:dumps,dump,loads,load

Tips:
可以把python中任意的数据类型序列化
由于是二进制内容,需要在每个模式后面加b进行写入
支持分批次load
都是二进制的

dumps

pickle.dumps(obj[, protocol])

将obj对象序列化为string形式,而不是存入文件中

loads

pickle.loads(string)

反序列化

Tips:dump()函数能一个接着一个地将几个对象序列化存储到同一个文件中,随后调用load()来以同样的顺序反序列化读取这些对象

dump

pickle.dump(obj,file,[protocol])

参数说明:
obj:想要序列化的obj对象
file:文件名称
protocol:序列化使用的协议,如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本

load

pickle.load(file)

将file中的对象序列化读取

例子

import pickle

dic = {'k1':'v1','k2':'v2'}
str_dic = pickle.dumps(dic,)
print(str_dic)

dic2 = pickle.loads(str_dic)
print(dic2)

shelve

比pickle用起来更简单
将对象保存到文件里面,缺省(即默认)的数据存储文件是二进制

  • 用法

    使用时,只需要使用open函数获取一个shelf对象,然后对数据进行增删改查操作
    在完成工作,并且将内存存储到磁盘中,最后调用close函数变回将数据写入文件

shelve.open

创建或打开一个shelve对象
shelve默认打开方式支持同时读写操作

shelve.open(filename, flag=’c’, protocol=None, writeback=False)

# 参数说明
* filenam:关联的文件路径
* flag [可选]:默认为‘c’,如果数据文件不存在,就创建,允许读写;可以是: ‘r’: 只读;’w’: 可读写; ‘n’: 每次调用open()都重新创建一个空的文件,可读写
* protocol:是序列化模式,默认值为None。具体还没有尝试过,从pickle的资料中查到以下信息【protocol的值可以是1或2,表示以二进制的形式序列化】
* writeback:默认为False。当设置为True以后,shelf将会将所有从DB中读取的对象存放到一个内存缓存。当我们close()打开的shelf的时候,缓存中所有的对象会被重新写入DB

由于shelve在默认情况下是不会记录待持久化对象的任何修改的,所以我们在shelve.open()时候需要修改默认参数,否则对象的修改不会保存(writeback参数)

writeback缺点:使用writeback以后,shelf在open()的时候会增加额外的内存消耗,并且当DB在close()的时候会将缓存中的每一个对象都写入到DB,这也会带来额外的等待时间。因为shelve没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入
为了保存增,删,改的内容,建议显示的标明writeback=True

shelve模块限制

它不支持多个应用同一时间往同一个DB(文件)进行写操作,所以如果只需进行读操作,可以修改默认参数flag=’r’ 让shelve通过只读方式打开DB(文件)
python2.7有效

存储文件在键(如果使用现有的key,将会覆盖旧数据)
格式:文件句柄[key] = data

import shelve

d = shelve.open('pass')
# d['key'] = ['xxx','aaa']
# d.close()

取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错

import shelve

d = shelve.open('pass')
existing = d['key']
d.close()
print(existing)

writeback(没开的情况下,增,删,改都不会记录)

import shelve

# 没开的情况
d = shelve.open('pass')
d['key'] = ['1111','2222']
d['key'].append('333')
print(d['key'])
结果:['1111', '2222']

# 开
d = shelve.open('pass',writeback=True)
d['key'] = ['1111','2222']
d['key'].append('333')
print(d['key'])
结果:['1111', '2222', '333']

shelve.close

shelve.close()

同步关闭shelve对象

Tips:每次使用完毕,都必须确保shelve对象被安全关闭,同样可以使用with语句

with shelve.open('span') as db:
    db['eggs'] = 'eggs'

只读

import shelve

f = shelve.open('shelve_file', flag='r')
existing = f['key']
f.close()
print(existing)

Python      Python

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

PrettyTable
Python打包成exe文件