python3序列化_python3之序列化(pickle&json&shelve)

本文详细介绍了Python中的数据持久化模块pickle、json和shelve的使用方法。pickle模块可以将Python对象序列化和反序列化,支持所有Python数据类型,而json模块则用于轻量级的数据交换,主要用于跨语言通信,仅支持基本数据类型。shelve模块提供键值对的持久化存储,适合简单的数据存储需求。文章还对比了这三个模块的特点和适用场景。
摘要由CSDN通过智能技术生成

1、pickle模块

python持久化的存储数据:

python程序运行中得到了一些字符串,列表,字典等数据,想要长久的保存下来,方便以后使用,而不是简单的放入内存中关机断电就丢失数据。python模块大全中pickle模块就排上用场了, 他可以将对象转换为一种可以传输或存储的格式。

pickle模块将任意一个python对象转换成一系统字节的这个操作过程叫做串行化对象。

python的pickle模块实现了python的所有数据序列和反序列化。基本上功能使用和JSON模块没有太大区别,方法也同样是dumps/dump和loads/load。cPickle是pickle模块的C语言编译版本相对速度更快。

与JSON不同的是pickle不是用于多种语言间的数据传输,它仅作为python对象的持久化或者python程序间进行互相传输对象的方法,因此它支持了python所有的数据类型。

importpickle

data2= [1,2,3,4]

det_str=pickle.dumps(data2)print(det_str)#output: 输出为二进制格式

b'\x80\x03]q\x00(K\x01K\x02K\x03K\x04e.'

#将数据序列化后存储到文件中

f = open('test.txt','wb') #pickle只能以二进制格式存储数据到文件

data = {'k1':'python','k2':'java'}

f.write(pickle.dumps(data))#dumps序列化源数据后写入文件

f.close()#反序列化读取源数据

importpickle

f= open('test.txt','rb')

da= pickle.loads(f.read()) #使用loads反序列化

print(da)

dumps和dump,load和loads的区别:

dumps是将对象序列化

dump是将对象序列化并保存到文件中

loads将序列化字符串反序列化

load将序列化字符串从文件读取并反序列化

importpickle

data1= [1,'a',2,'b',3,'c']

pi= pickle.dumps(data1) #序列化对象

print(pi)print(pickle.loads(pi)) #反序列化对象

f= open('test1.txt','wb')

data2= ['py','th','on',123]

pickle.dump(data2,f)#序列化对象到文件

f = open('test1.txt','rb')

red= pickle.load(f) #从文件中反序列化对象

print(red)

2、json模块

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。

json.dump(obj,fp,*,skipkeys = False,ensure_ascii = True,check_circular = True,indent = None,separators = None,default = None,sort_keys = False,** kw)

将obj对象格式化并存储到文件对象中,文件必须为可写的文件句柄,json只产生str对象,不支持bytes对象,所以fp.write()必须支持str输入

skipkeys如果为True,对象的基本类型必须是str,int,float,bool,None

ensure_ascii=True,如果为true则所以传入的非ASCII字符都被转义,如果为false则字符将原样输出

check_circular=True,如果为true容器类型的循环引用检查将被跳过

indent=None,表示数组元素和对象将按指定的值缩进,可以是整数或字符串如'\t'

sort_keys=False,如果为True字典的输出将按键排序

importjson

data=[{'k1':'v1','k2':'v2'},{'k3':'v3','k4':'k4'},{'k6':'v6','k5':'k5'}]

with open('test.txt','w') as pf:

json.dump(data,pf,indent=2,sort_keys=True)

pf.close()#output

[

{"k1": "v1","k2": "v2"},

{"k3": "v3","k4": "k4"},

{"k5": "k5","k6": "v6"}

]

json.dumps(obj,*,skipkeys = False,ensure_ascii = True,check_circular = True,indent = None,separators = None,default = None,sort_keys = False,** kw)

将obj对象格式化为str对象,参数含义和dump相同

importjson

data=[{'k1':'v1','k2':'v2'},{'k3':'v3','k4':'k4'},{'k6':'v6','k5':'k5'}]

pi= json.dumps(data,indent=2,sort_keys=True)print(type(pi))print(pi)

p2=json.loads(pi)print(type(p2))print(p2)#[

{"k1": "v1","k2": "v2"},

{"k3": "v3","k4": "k4"},

{"k5": "k5","k6": "v6"}

][{'k1': 'v1', 'k2': 'v2'}, {'k3': 'v3', 'k4': 'k4'}, {'k5': 'k5', 'k6': 'v6'}]

json.load(fp,*,cls=None,object_hook=None,parse_float=None,parse_int=None,parse_constant=None,object_pairs_hook=None,**kw)

将文件对象反序列化为python对象,选项参数用来指定类型解码,在python3.6中fp可以使用二进制文件

importjson

with open('test.txt','rb') as fp:

data1=json.load(fp)print(type(data1))print(data1)#[{'k1': 'v1', 'k2': 'v2'}, {'k3': 'v3', 'k4': 'k4'}, {'k5': 'k5', 'k6': 'v6'}]

json.loads(s,*,encoding=None,cls=None,object_hook=None,parse_float=None,parse_int=None,parse_constant=None,object_pairs_hook=None,**kw)

将json文档的实例反序列化为python对象,参数含义同load()相同

importjson

with open('test.txt','rb') as fp:

data1=json.loads(fp.read())print(type(data1))print(data1)

3、json与pickle模块的区别

1、JSON只能处理基本数据类型。pickle能处理所有Python的数据类型。

2、JSON用于各种语言之间的字符转换。pickle用于Python程序对象的持久化或者Python程序间对象网络传输,但不同版本的Python序列化可能还有差异。

4、shelve模块

shelve与pickle类似用来持久化数据的,不过shelve是以键值对的形式,将内存中的数据通过文件持久化,值支持任何pickle支持的python数据格式,它会在目录下生成三个文件。

>>> importshelve>>> importtab>>> s = shelve.open('test_s.db') #创建shelve并打开

>>> s['k1']={'int':10,'float':8.8,'string':'python'} #写入数据

>>> s.close() #关闭文件

>>> s = shelve.open('test_s.db') #打开文件

>>> print(s['k1']) #访问shelve中的数据

{'float': 8.8, 'string': 'python', 'int': 10}>>> print(s['k1']['int'])10

>>> s.close()

对于存储的key,value值,只能添加key,value,可修改整个value,不能单独修改列表或字典中的元素

>>> s = shelve.open('test_s.db',flag='r')>>> print(s['k1'])

{'float': 8.8, 'string': 'python', 'int': 10}>>> s['k2']=[1,2,3] #添加数据

>>> print(s['k2'])

[1, 2, 3]>>> s['k2'][0]=99 #修改存储的value的单个值时不生效也不报错

>>> print(s['k2'])

[1, 2, 3]>>>s.close()>>> s = shelve.open('test_s.db',flag='c')>>>s.keys()

KeysView()>>>len(s)2

>>> s['k2']=(33,44) #可以修改key的value

>>> print(s)

>>> print(s['k2'])

(33, 44)

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

上面这个例子中,由于一开始我们使用了缺省参数shelve.open()了,因此修改的值即使我们s.close()也不会被保存。

所以当我们试图让shelve去自动捕获对象的变化,我们应该在打开shelf的时候将writeback设置为True。当我们将writeback这个flag设置为True以后,shelf将会将所有从DB中读取的对象存放到一个内存缓存。当我们close()打开的shelf的时候,缓存中所有的对象会被重新写入DB。

>>> s = shelve.open('test_s.db',writeback=True) #使用回写功能打开

>>> print(s['k1']) #初始值

{'float': 8.8, 'string': 'python', 'int': 10}>>> print(s['k2'])

(33, 44)>>> s['k1']['float']='99.99' #修改字典中的元素

>>> print(s['k1']) #成功修改

{'float': '99.99', 'string': 'python', 'int': 10}

writeback方式有优点也有缺点。优点是减少了我们出错的概率,并且让对象的持久化对用户更加的透明了;但这种方式并不是所有的情况下都需要,首先,使用writeback以后,shelf在open()的时候会增加额外的内存消耗,并且当DB在close()的时候会将缓存中的每一个对象都写入到DB,这也会带来额外的等待时间。因为shelve没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入。

>>> print(s['k1'])

{'float': '99.99', 'string': 'python', 'int': 10}>>> s['k1']['list']=[1,2,3]>>> s['k1']['tuple']=(4,5,6)>>> s['k1']['dic']={'a':123,'b':456}>>> print(s['k1'])

{'dic': {'b': 456, 'a': 123}, 'int': 10, 'float': '99.99', 'string': 'python', 'tuple': (4, 5, 6), 'list': [1, 2, 3]}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值