zoukankan      html  css  js  c++  java
  • 序列化 pickle(重点) shelve json(重点)

    一. 什么是序列化

      在我们存储数据或者网络传输数据的时候. 需要对我们的对象进行处理.

    把对象处理成方便存储和传输的数据格式. 这个过程叫序列化. 不同的序列化, 结果也不同.

    但是目的是一样的. 都是为了存储和传输.在python中存在三种序列化的方案.

      1. pickle. 可以将我们python中的任意数据类型转化成bytes并写入到⽂文件中. 同样也
    可以把⽂件中写好的bytes转换回我们python的数据. 这个过程被称为反序列化
      

      2. shelve. 简单另类的一种序列化的方案. 有点儿类似后面我们学到的redis. 可以作为
    一种小型的数据库来使用
      

      3. json. 将python中常见的字典, 列表转化成字符串. 是⽬前前后端数据交互⽤用频率
    最⾼的⼀种数据格式.


    二. pickle(重点)
      pickle用起来很简单. 说⽩了. 就是把我们的python对象写入到⽂件中的⼀种解决方案.
    但是写入到⽂件的是bytes. 所以这东⻄不是给人看的. 是给机器看的.

    import pickle
    class Cat:
    def __init__(self, name, age):
    self.name = name
    self.age = age
    def catchMouse(self):
    print(self.name, "抓老鼠")
    c = Cat("jerry", 18)
    bs = pickle.dumps(c) # 序列化一个对象.
    print(bs) # 一堆二进制. 看不懂
    cc = pickle.loads(bs) # 把二进制反序列化成我们的对象
    cc.catchMouse() # 猫依然是猫. 还可以抓老鼠

      pickle中的dumps可以序列化一个对象. loads可以反序列化⼀个对象. 我们使用dump
    还可以直接 把一个对象写入到文件中

    # f = open("cat", mode="wb")
    # pickle.dump(c, f) # 写入到⽂文件中
    # f.close()
    f = open("cat", mode="rb")
    cc = pickle.load(f) # 从文件中读取对象
    cc.catchMouse()

    pickle还⽀持多个对象的写出.

    lst = [Cat("jerry", 19), Cat("tommy", 20), Cat("alpha", 21)]
    f = open("cat", mode="wb")
    for el in lst:
    pickle.dump(el, f) # 写入到⽂文件中
    f.close()
    f = open("cat", mode="rb")
    for i in range(len(lst)):
    cc = pickle.load(f) # 从文件中读取对象
    cc.catchMouse()

      但是这样写并不够好. 因为读的时候. 并不能知道有多少对象要读. 这里记住, 不能一行
    一行的读. 那真的要写入或者读取多个内容怎么办? 很简单. 装list里. 然后读取和写入都用
    list

    lst = [Cat("jerry", 19), Cat("tommy", 20), Cat("alpha", 21)]
    f = open("cat", mode="wb")
    pickle.dump(lst, f)
    f = open("cat", mode="rb")
    ll = pickle.load(f)
    for el in ll:
    el.catchMouse()

      记住一点, pickle序列化的内容是二进制的内容(bytes) 不是给人看的.

    import pickle
    #
    class Elephant:
        def __init__(self, name, weight, height):
            self.name = name
            self.weight = weight
            self.height = height
    
        def tiaoxi(self):
            print(f"{self.name}大象特别喜欢调戏人")
    
    # e = Elephant("宝宝", "185T", "175")
    # e.tiaoxi()
    #
    # # 序列化
    # bs = pickle.dumps(e) # 把对象进行序列化
    # print(bs)
    #
    # bs = b'x80x03c__main__
    Elephant
    qx00)x81qx01}qx02(Xx04x00x00x00nameqx03Xx06x00x00x00xe5xaex9dxe5xaex9dqx04Xx06x00x00x00weightqx05Xx04x00x00x00185Tqx06Xx06x00x00x00heightqx07Xx03x00x00x00175qx08ub.'
    # # 发序列化
    # dx = pickle.loads(bs) # 发序列化. 得到的是大象
    # dx.tiaoxi()
    
    
    # e1 = Elephant("宝宝", "185T", "175")
    # e2 = Elephant("宝贝", "120T", "120")
    # f = open("大象", mode="wb")
    # # 这也是序列化
    # pickle.dump(e1, f) # 没有s的这个方法是把对象打散写入到文件, 序列化的内容不是给人看的
    # pickle.dump(e2, f) # 没有s的这个方法是把对象打散写入到文件, 序列化的内容不是给人看的
    
    # f = open("大象", mode="rb")
    # while 1:
    #     try:
    #         obj = pickle.load(f)
    #         obj.tiaoxi()
    #     except Exception:
    #         break
    
    
    
    # e1 = Elephant("宝宝", "185T", "175")
    # e2 = Elephant("宝贝", "120T", "120")
    #
    # lst = [e1, e2]
    #
    # pickle.dump(lst, open("大象", mode="wb"))
    
    
    # 读
    # lst = pickle.load(open("大象", mode="rb"))
    # for dx in lst:
    #     dx.tiaoxi()

     

     

    shelve


    shelve提供python的持久化操作. 什么叫持久化操作呢? 说白话,就是把数据写到硬盘上.
    在操作shelve的时候非常的像操作一个字典. 这个东西到后期. 就像redis差不多.

    import shelve
    shelf = shelve.open("sylar")
    # shelf["jay"] = "周杰伦"
    print(shelf['jay'])
    shelf.close()

    感觉到了么. 这个⿁东⻄和字典差不多. 只不过你的字典是⼀个⽂件. 接下来, 我们存储
    一些复杂的数据

    = shelve.open("sylar")
    # s["jay"] = {"name":"周杰伦", "age":18, "hobby":"哄⼩小孩"}
    print(s['jay'])
    s.close()

    但是,有坑

    s = shelve.open("sylar")
    s['jay']['name'] = "胡辣汤" # 尝试改变字典中的数据
    s.close()
    s = shelve.open("sylar")
    print(s['jay']) # 并没有改变
    s.close()

    解决方案

    s = shelve.open("sylar", writeback=True)
    s['jay']['name'] = "胡辣汤" # 尝试改变字典中的数据
    s.close()
    s = shelve.open("sylar")
    print(s['jay']) # 改变了.
    s.close()

    writeback=True可以动态的把我们修改的信息写入到文件中. 而且这个鬼东西还可以删
    除数据. 就像字典一样. 上一波操作

    s = shelve.open("sylar", writeback=True)
    del s['jay']
    s.close()
    s = shelve.open("sylar")
    print(s['jay']) # 报错了, 没有了
    s.close()
    s = shelve.open("sylar", writeback=True)
    s['jay'] = "周杰伦"
    s['wlj'] = "王⼒力力宏"
    s.close()
    s = shelve.open("sylar")
    for k in s: # 像字典一样遍历
    print(k)
    print(s.keys()) # 拿到所有key的集合
    for k in s.keys():
    print(k)
    for k, v in s.items(): # 像字典一样操作
    print(k, v)
    s.close()

      综上shelve就当成字典来用就行了. 它比redis还简单.......

     

     

    json(重点)


    终于到json了. json是我们前后端交互的枢纽. 相当于编程界的普通话. ⼤家沟通都用
    json. 为什么这样呢? 因为json的语法格式可以完美的表⽰出一个对象. 那么是json: json全
    称javascript object notation. 翻译过来叫js对象简谱. 

    json(重点中的重点)
    json你可以认为是python中的字典. 有一点点的不一样
    python:   True    False   None
    json:     true    false    null

    1. dumps() 把对象序列化成json
    2. loads() 把json反序列化成对象

    3. dump() 把对象序列化写入文件
    4. load() 把文件中的内容反序列化成对象

       我们的程序是在python里写的. 但是前端是在JS那边来解析json的. 所以. 我们需要把我们程序产生的字典转化成json格式的json串(字符串). 然后网络传输. 那边接收到了之后. 它爱怎么处理是它的事情. 那, 如何把字典转化成我们的json格式的字符串呢?很简单, 上代码.

    import json
    dic = {"a": "⼥王", "b": "萝莉", "c": "小清新"}
    s = json.dumps(dic) # 把字典转化成json字符串
    print(s) # {"a": "u5973u738b", "b": "u841du8389", "c":
    "u5c0fu6e05u65b0"}

    结果很不友好啊. 那如何处理理中文呢? 在dumps的时候给出另一个参数
    ensure_ascii=False就可以了

    import json
    dic = {"a": "女王", "b": "萝莉", "c": "小清新"}
    s = json.dumps(dic, ensure_ascii=False) # 把字典转化成json字符串
    print(s) # {"a": "女王", "b": "萝莉", "c": "小清新"}

    搞定了. 接下来. 前端给你传递信息了. 你要把前端传递过来的json字符串转化成字典.

    import json
    s = '{"a": "女王", "b": "萝莉", "c": "小清新"}'
    dic = json.loads(s)
    print(type(dic), dic)

    搞定. 是不是很简单. 以上两个代码要求. 记住, 理解, 背会

    json也可以像pickle一样把序列化的结果写入到文件中.

    dic = {"a": "⼥女女王", "b": "萝莉", "c": "⼩小清新"}
    f = open("test.json", mode="w", encoding="utf-8")
    json.dump(dic, f, ensure_ascii=False) # 把对象打散成json写⼊入到⽂文件中
    f.close()

    同样也可以从⽂件中读取⼀一个json

    f = open("test.json", mode="r", encoding="utf-8")
    dic = json.load(f)
    f.close()
    print(dic)

     

    注意. 我们可以向同一个⽂件中写入多个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()

      这在读取的时候是无法正常读取的. 那如何解决呢? 两套⽅案. 方案一. 把所有的内容准备好统一
    进行写入和读取. 但这样处理, 如果数据量小还好. 数据量大的话, 就不够友好了. 方案二. 不用
    dump. 改用dumps和loads. 对每一行分别进行处理.

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

     

     

     

     

  • 相关阅读:
    5 float f = 3.4,是否正确
    4 String是基本数据类型吗
    3 访问修饰符public,private,protected以及不写(默认)时的区别
    1 请谈谈面向对象的三大特征?
    接口和抽象类有什么区别
    2 Java中 == 和 equals 和 hashCode 的区别
    java中重载(overload)与重写(override)的区别
    servlet中请求转发(forword)和重定向(redirect)的区别
    团队-项目名称五子棋-团队一阶段互评
    团队-项目名称五子棋-开发环境搭建过程
  • 原文地址:https://www.cnblogs.com/H1050676808/p/10186850.html
Copyright © 2011-2022 走看看