python 序列化
一、序列化简介
在我们存储数据或者网络传输数据的时候,需要对我们的对象进行处理,把对象处理成方便存储或者传输的数据格式,这个过程叫序列化。
不同的序列化,结果也不同,但是目的都是一样的,都是为了存储和传输。
在python中存在三种序列化的方案。
1、pickle:可以将我们python中的任意数据类型转换为bytes类型数据,并可以出入文件中,同样也可以吧文件中写好的bytes类型数据转换为我们python中的数据类型,这个过程称为反序列化。
2、shelve:简单的另类的一种序列化的放哪,有点类似redis,可以称为一种微小的数据库,用法参照字典使用。
3、json:将python中常见的字典,列表转换为字符串。是母亲啊前后端数据交互使用的最频繁的一种数据格式。
二、pickle
pickle.dumps(数据) 表示将python中的数据类型转换为bytes类型
import pickle
lst=[1,2,3]
b=pickle.dumps(lst)
print(b)#b'x80x03]qx00(Kx01Kx02Kx03e.'
pickle.loads(bytes) 表示将bytes转换为python中的数据类型
import pickle b=b'x80x03]qx00(Kx01Kx02Kx03e.' lst=pickle.loads(b) print(lst[:]) #[1, 2, 3]
pickle.dump(数据,file) 表示将python中的数据写入到file 文件中
import pickle class Cat: def __init__(self,name,color): self.name=name self.color=color def chi(self): print("%s猫会吃老鼠" % self.name) c1=Cat("波斯猫1","红色1") c2=Cat("波斯猫2","红色2") c3=Cat("波斯猫3","红色3") c4=Cat("波斯猫4","红色4") lst=[c1,c2,c3,c4] #对象装如列表 pickle.dump(lst,open("mao.db",mode="wb"))#写入列表
pickle.load(file) 表示把文件中的types转换为python中的数据
obj_lst=pickle.load(open("mao.db",mode="rb")) for cat in obj_lst: cat.chi()
注释:记住⼀点, pickle序列化的内容是⼆进制的内容(bytes) 不是给⼈看的 。
三、shelve
shelve提供python的持久化操作,把数据写入到硬盘里面,在操作shelve时候非常像操作字典,我们可以当作字典进行操作。
shelve.open(file) 创建文件名字为file的文件,拿到句柄
s = shelve.open("sylar") # s["jay"] = {"name":"周杰伦", "age":18, "hobby":"哄⼩孩"} print(s['jay']) s.close()
直接修改shelve中的value的值可能存在问题,我们需要加witeback解决这个问题
错误示例:此处有坑!!!
s = shelve.open("sylar") s['jay']['name'] = "胡辣汤" # 尝试改变字典中的数据 s.close() s = shelve.open("sylar") print(s['jay']) # 并没有改变 s.close()
修改的value内部的子元素时候,不会自动写入文件中,我们需要带入回写参数 (witeback=True)
s = shelve.open("sylar", writeback=True) s['jay']['name'] = "胡辣汤" # 尝试改变字典中的数据 s.close() s = shelve.open("sylar") print(s['jay']) # 改变了. s.close()
删除元素 : d=shelve.open(file) -> del d[key]
增加元素 :d=shelve.open(file) -> d[new_key]=value
修改元素:d=shelve.open(file,writeback=True) -> d[old_key]=new_value / d[old_key][" "][" "]=" "
查询元素: d=shelve.open(file) -> d[key]
四、json(javascript object notation )(重点)
json牛逼哦,json是我们前后端交互的枢纽。
来一段字符看看
wf = { "name":"汪峰", "age":18, "hobby":"上头条", "wife":{ "name":'⼦怡', "age":19, "hobby":["唱歌", "跳舞", "演戏"] } }
咦!
python中叫字典!(字典呀)
json中交字符串!(字符串呀)
我们发现⽤这样的数据结构可以完美的表⽰出任何对象. 并且可以完整的把对象表⽰出来. 只要代码格式比较好. 那可读性也是很强的. 所以⼤家公认⽤这样⼀种数据结构作为数据交互的格式.
再来回顾一下我们以前的xml,看着好难受哦!!!
<?xml version="1.0" encoding="utf-8" ?> <wf> <name>汪峰</name> <age>18</age> <hobby>上天</hobby> <wife> <name>子怡</name> <hobby> <hobby1>唱歌</hobby1> <hobby1>跳舞</hobby1> <hobby1>演戏</hobby1> </hobby> </wife> </wf>
面对如此牛逼的json,我们的程序在python中写的,现在我们就来一起学习如何将我们产生的字典转换为json字符串,然后怎么读取网页上的json。
json 用法:核心就是将字符串 - >字典 ,字典- >字符串
json.dumps(dic)
d={"a":"小萝莉","b":"大妈","c":"猥琐大叔","d":False,"e":None} s=json.dumps(d) print(s) #结果{"a": "u5c0fu841du8389", "b": "u5927u5988", "c": "u7325u7410u5927u53d4", "d": false, "e": null}
结果很不友好,原因是因为json默认的是ascii编码的,不能识别中文。
解决方法:ensure_ascii=False
json.dumps(dic,ensure_ascii=False) 可是识别中文
import json d={"a":"小萝莉","b":"大妈","c":"猥琐大叔","d":False,"e":None} s=json.dumps(d,ensure_ascii=False) print(s)
json.loads(s) 表示将字符串s转换为响应的字典
import json s = '{"a": "⼥王", "b": "萝莉", "c": "⼩清新"}' dic = json.loads(s) print(type(dic), dic)
json.dump(dic,file) 表示把字典dic转换为json字符串放入到文件file中
dic = {"a": "⼥王", "b": "萝莉", "c": "⼩清新"} f = open("test.json", mode="w", encoding="utf-8") json.dump(dic, f, ensure_ascii=False) # 把对象打散成json写⼊到⽂件中 f.close()
json.load(file) 表示一次性读取文件中所有内容,并把Json字符串转换为字典
f = open("test.json", mode="r", encoding="utf-8") dic = json.load(f) f.close() print(dic)
注意:我们可以一次性写入多个json,但是我们不能一次性读出,我们可以把json字符串类型的字典一行一行存放,然后遍历文件,一行一行读出
import json lst = [{"a": 1}, {"b": 2}, {"c": 3}] f = open("test.json", mode="w", encoding="utf-8") for el in lst: json.dump(el, f) f.close()
优化代码
import json lst = [{"a": 1}, {"b": 2}, {"c": 3}] # 写⼊ f = open("test.json", mode="w", encoding="utf-8") for el in lst: s = json.dumps(el, ensure_ascii=True) + " " f.write(s) f.close() # 读取 f = open("test.json", mode="r", encoding="utf-8") for line in f: dic = json.loads(line.strip()) print(dic) f.close()