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()