序列化模块

1.Json模块

a:什么是json模块:

json模块用于字符串和Python数据类型间进行转换

b:json的四个功能:

1)dumps:将列表,字典,元组,数字-->字符串

  dumps直接操作变量,操作完成变成了一个字符串变量;

import json
dic = {'a':2,'b':4,'d':[5,6,8,7]}
str_dict = json.dumps(dic)
print(str_dict,type(str_dict))
#输出结果:
{"a": 2, "b": 4, "d": [5, 6, 8, 7]} <class 'str'>

@结果为字符串类型,但是这个新变量中的字符串为双引号,且只能为双引号;

  dumps中的参数:

data = {'username':['李华','二愣子'],'sex':'male','age':16}
json_dic2 = json.dumps(data,sort_keys=True,indent=4,separators=(',',':'),ensure_ascii=False)
print(json_dic2)
#当你的字典特别长或则特别大的时候就会写不下,所以这时会用到它的参数调整你输出的格式
#sort_keys:对字典的key值进行了排序,
#ident表示每一行的缩进
#separate表示分隔符,

这种格式一般不在存文件时应用该方法,只是让程序员看起来方便,因为相对浪费空间;

2)loads

  loads就是将字符串变量转为相应格式的数据类型;

import json
dic = {'a':2,'b':4,'d':[5,6,8,7]}
str_dict = json.dumps(dic)
print(str_dict,type(str_dict))
#将字典转为字符串
new_dic = json.loads(str_dict)
print(new_dic,type(new_dic))
#将字符串转为字典
#输出结果
{"a": 2, "b": 4, "d": [5, 6, 8, 7]} <class 'str'>
{'a': 2, 'b': 4, 'd': [5, 6, 8, 7]} <class 'dict'>

3)dump

  dump应用于你只想往文件写入,将数据类型相互转换 

import json
dic = {'a':2,'b':4,'d':[5,6,8,7]}
with open('aaa',mode='a+',encoding='utf-8')as f:
    json.dump(dic,f)

#文件 aaa
{"a": 2, "b": 4, "d": [5, 6, 8, 7]}
#相当于默认帮你执行了f.write()方法
dic = {'a':2,'b':4,'d':'中国'}

#当dump方法遇见中文的时候

json.dump(dic,f)
 #{"a": 2, "b": 4, "d": "u4e2du56fd"}

#修改参数ensure_asill=False就会切换为utf-8
json.dump(dic,f,ensure_ascii=False)
#{"a": 2, "b": 4, "d": "中国"}

4)load

  load将文件中的字符串转为相应的数据类型,而且一行不能有多个数据类型

with open('aaa',encoding='utf-8')as f:
    print(json.load(f))
#输出结果:
{'a': 2, 'b': 4, 'd': '中国'}

5)json的优缺点:

优点:可以跨平台语言,支持所有语言;

缺点:

  1)对字典的key值的限制,再转为字符串时,key值只能为字符串,如果是数字,会强转为字符串,然后你再转回时,也就变为字符串了;

import json
dic = {1:2,'b':4,'d':5}
print(json.dumps(dic))
print(json.loads(json.dumps(dic)))
#输出结果
{"1": 2, "b": 4, "d": 5}
{'1': 2, 'b': 4, 'd': 5}

  2)对于字典的value值如果为元组,会请转为列表;

import json
dic = {1:2,'b':4,'d':(1,2,3)}
print(json.dumps(dic))
print(json.loads(json.dumps(dic)))
#输出结果
{"1": 2, "b": 4, "d": [1, 2, 3]}
{'1': 2, 'b': 4, 'd': [1, 2, 3]}

#key值不支持是元组TypeError: keys must be a string

  3)json中的要操作的文件如果有引号,必须为双引;

  4)当有中文格式时,要将dumps的ensure_ascii设置为False,才能进行转换;

  5)如果想要多行写入,然后读取,要利用dumps和loads一起使用:

import json
dic = {2:2,'b':4,'d':(1,2,3)}
lst = [1,2,'a',(1,2,3)]
with open('aaa','w')as f:
    f.write(json.dumps(dic)+'
')
    f.write(json.dumps(lst)+'
')
with open('aaa')as f1:
    for line in f1:
        print(json.loads(line))

2.pickle模块

a:和json模块一样,同样也是将数据类型转为字符串

b:pickle可以将任何数据类型转为字符串;

c:pickele是以bytes格式显示的;

d:pickle的dumps和loads,dump和load跟json一样

e:不同点是pickle可以对对象操作,转为字符串

import pickle
class A:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def read(self):
        print(222)
a = A('name',10)
with open('aaa',mode = 'wb')as f:
    pickle.dump(a,f)
with open('aaa','rb')as f1:
    ret = pickle.load(f1)
    print(ret.__dict__)
    ret.read()
#可用于对游戏的存档和读档

#pickle的应用,将对象一一提取出来,用一个异常处理

import pickle
class A:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def read(self):
        print(222)
a = A('name1',10)
b = A('name2',15)
c = A('name3',18)
with open('aaa',mode = 'wb')as f:
    pickle.dump(a,f)
    pickle.dump(b,f)
    pickle.dump(c,f)
with open('aaa','rb')as f1:
    while True:
        choose = True
        try:
            obj = pickle.load(f1)
            if 'name5' == obj.name:
                print(obj.__dict__)
                break
        except EOFError:
            choose = False
            break
if choose == False:        #如果没有此对象,给一个提示
    print('None')
#输出结果:
None

这样就可以将对象的属性一一保存起来,等到用到的时候再提取出来;

3.shelve模块  

a:shelve也是python提供给我们的序列化工具,比pickle用起来更简单一些。
  shelve只提供给我们一个open方法,是用key来访问的,使用起来和字典类似。

import shelve
f = shelve.open('shelve_file')
f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'}  #直接对文件句柄操作,就可以存入数据
f.close()

import shelve
f1 = shelve.open('shelve_file')
existing = f1['key']  #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错
f1.close()
print(existing)

这个模块有个限制,它不支持多个应用同一时间往同一个DB进行写操作。所以当我们知道我们的应用如果只进行读操作,我们可以让shelve通过只读方式打开DB

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

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

总结:序列化的好处:

1.以某种储存形式使自定义对象持久化;

2.将对象从一个地方传递到另一个地方;

3.使程序更具有维护性

原文地址:https://www.cnblogs.com/0627zhou/p/9448199.html