• day022(初识模块)序列化(pickle,shelve,json)、configparser模块


    本节内容:

    1、什么是序列化
    2、pickle(重点)
    3、shelve 类似小型数据库
    4、json(重点)
    5、configparser模块

    一、什么是序列化

    在我们存储数据或者⽹络传输数据的时候. 需要对我们的对象进⾏处理.
    把对象处理成⽅便存储和传输的数据格式. 这个过程叫序列化.
    不同的序列化, 结果也不同. 但是⽬的是⼀样的. 都是为了存储和传输.

    1、在python中存在三种序列化的⽅案

    1. pickle. 可以将我们python中的任意数据类型转化成bytes并写入到⽂件中.
    同样也可以把⽂件中写好的bytes转换回我们python的数据. 这个过程被称为反序列化
    
    2. shelve. 简单另类的⼀种序列化的⽅案. 有点⼉类似后⾯我们学到的redis.
    可以作为⼀种⼩型的数据库来使⽤
    
    3. json. 将python中常⻅的字典, 列表转化成字符串.
    是⽬前前后端数据交互使⽤频率最⾼的⼀种数据格式.

    二、pickle(重点)

    pickle⽤起来很简单. 说⽩了.
    就是把我们的python对象写入到⽂件中的⼀种解决⽅案.
    但是写入到⽂件的是bytes. 所以这东⻄不是给⼈看的. 是给机器看的.
        序列化 把对象打散成二进制字节 bytes

    1、 pickle 把一个对象转化成bytes写入到文件

    pickle.dumps() 把对象转换成bytes
    pickle.loads() 把bytes转化成对象
    
    pickle.dump() 把对象转换成bytes. 写入到文件
    pickle.load() 把文件中的bytes读取. 转化成对象

    2、dumps和loads只是序列化和反序列化功能,

    pickle中的dumps可以序列化⼀个对象. loads可以反序列化⼀个对象.
    注意:没有写入文件和读取文件的功能

    fe:

    import pickle
    
    class Cat:
        def __init__(self, name, color):
            self.name = name
            self.color =color
    
        def chi(self):
            print("%s猫可以吃鱼" % self.name)
    
    c = Cat("小白", "红色")
    bs = pickle.dumps(c)  # dumps序列化对象,把一个对象转化成 bytes类型,进行传输
    print(bs)
    
    s = pickle.loads(bs)  # loads() 将字节还原对象, 对象还是那个对象,还可以执行吃鱼,但是创建猫的类不能没有,这个就好比是图纸,没有了无法复原
    print(s)
    print(s.name)
    
    # 区别dump和load
    
    c2 = Cat("小白2", "红色1")
    
    pickle.dump(c, open("猫.db", mode = "wb"))  # 把对象以二进制类型,写入到文件中
    pickle.dump(c2, open("猫.db", mode = "ab"))  # 重新打开写入用mode = "ab"
    
    cc = pickle.load(open("猫.db", mode = "rb"))  # 从文件中读取到对象
    cc.chi()
    print(cc.name) # 小白猫
    
    se = pickle.load(open("猫.db", mode = "rb")) # 再拿一次就是下一个对象了
    pirnt(se.name) # 小白2

    3、dump和load((反)序列化 + 写读文件)的功能

    这⾥记住, 不能⼀⾏⼀⾏的读. 那真的要写入或者读取多个内容怎么办?
    很简单. 装list⾥. 然后读取和写入都⽤list

    fe: 写入及读取多个对象

    import pickle
    class Cat:
        def __init__(self, name, age):
            self.name = name
            self.age = age
        def catchMouse(self):
            print(self.name, "抓⽼⿏")
    
    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()
    f.close()

    fe: pickle写注册登录的示例

    class User:
        def __init__(self, username, password):
            self.username = username
            self.password = password
    
    class Admin:
        def regist(self):
            user = input("请输入用户名:")
            pwd = input("请输入密码:")
            u = User(user, pwd)
            f = open("账户信息.txt", mode = "ab")
            pickle.dump(u, f) # 前面是内容,后面是内容
            print("注册成功!!!")
    
        def login(self):
            user = input("请输入用户名:")
            pwd = input("请输入密码:")
            f = open("账户信息.txt", mode = "rb")
            while 1:
                try: # 不知道文件中有多少个对象,所以要使用try,execpt来接收没有对象的错误
                    u = pickle.load(f) # 循环一次,拿到下一个对象, 跟__next__一样,只能向前,但是可以用seek(0),用光标调顺序
                    if u.name == user and u.password == pwd:
                        print("登录成功!!!")
                        break
                except Exception as e:
                    print("登录失败!!")
                    break
    
    a = Admin()
    
    # a.regist()
    # a.regist()
    # a.regist()
    # a.regist()
    
    a.login()

    三、shelve小型数据库(持久化操作)

    shelve提供python的持久化操作. 什么叫持久化操作呢?
    说⽩话,就是把数据写到硬盘上.
    redis, mongodb, dict类似
    在操作shelve的时候非常的像操作⼀个字典,
    直接用字典的功能操作shelve
    注意:
    writeback = True 这样才能实现回写更新

    1、基本操作

    fe1: 写入和读取

    import shelve
    
    d = shelve.open("文件")  # 文件类型的字典, 写文件名就行了,后面会默认加上.db
    d["疏影"] = "暗香"
    d.close()
    
    d = shelve.open("文件")
    print(d["疏影"])  # 查看
    d.close()

    有坑!!!

    fe2: 修改字典里面嵌套的字典,必须用writeback = True,才能回写修改成功

    import shelve
    # 如果是字典里面嵌套字典,那么要修改里面的内容的时候,就要加上writeback = True,回写更新
    
    d = shelve.open("文件")
    d["大明"] = {"名字": "朱元璋", "职业": "当皇帝", "儿子": {"名字": "朱棣", "职业": "造反"}} # 写入嵌套的字典
    d.close()
    
    d = shelve.open("文件")
    d["大明"]["儿子"]["职业"] = "勤王"  # 并没有在文件修改,只是在内存中改了,没有更新进文件
    d.close()
    
    d = shelve.open("文件")
    for k, v in d.items():
        print(k, v)
    
    d = shelve.open("文件", writeback = True)  # 必须写了writeback = True,才会回写更新
    d["大明"]["儿子"]["职业"] = "勤王"  # 可以对文件进行回写更新了
    d.close()
    
    d = shelve.open("文件")
    for k, v in d.items():
        print(k, v)

    四、json(重点掌握)

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

    1、字典转json字符串(用dumps),json字符串转字典(用loads)

    s = json.dumps(d, ensure_ascii = False)  # 默认用ascii码解析,所以要改,不要用ASCII解析中文
    import json
    
    # python中直接将字典或列表转换成json
    d = {"朝代": "大明", "高祖": "朱元璋", "永乐大帝": "朱棣"}
    
    s = json.dumps(d, ensure_ascii = False)  # 默认用ascii码解析,所以要改,不要用ASCII解析中文
    
    print(s)
    print(type(s))  # <class 'str'>
    
    # 把json字符串转换成字典
    s = '{"朝代": "大明", "高祖": "朱元璋", "永乐大帝": "朱棣"}'
    
    d = json.loads(s) # 把json转换成字典
    
    print(d)
    print(type(d))  # <class 'dict'>

    2、json写入和读取文件

    1.转换成json,并写入文件
    2.读取json,转换成字典

    fe: 用json写入及读取文件

    # 转换成json,并写入文件
    dic = {"朝代": "大明", "高祖": "朱元璋", "儿子":{"永乐大帝": "朱棣"}}
    
    f = open("json.json", mode = "w", encoding = "utf-8")
    json.dump(dic, f, ensure_ascii = False, indent = 4)  # indent 缩进  4个空格 = 一个tab
    
    
    # 读取json,转换成字典
    f = open("json.json", mode = "r", encoding = "utf-8") # 打开文件
    
    dic = json.load(f)  # 把json转换成字典
    print(dic)

    3、把一个对象转换成json

    class Car:
        def __init__(self, name, color):
            self.name = name
            self.color =color
    
    c = Car("宝马", "大红")
    
    s = json.dumps(c.__dict__, ensure_ascii = False)  # 方案一,通过__dict__,获得对象的字典,进行转换(转化的是字典)
    print(s) # 转换json成功,
    
    
    def func(obj):
        return {
            "self.name": obj.name,
            "self.color": obj.color
        }
    
    s = json.dumps(c,default = func, ensure_ascii = False)  # 方案二,通过函数,生成字典,来用json(转化的也是字典)
    print(s)
    
    
    # json转回对象
    
    s = '{"name": "宝马", "color": "大红"}'
    
    def func(dic):
        return Car(dic["name"],dic["color"])
    
    p = json.loads(s, object_hook = func) # 通过函数func把字典转换成对象
    print(p.name, p.color)

    五、configparser模块

    该模块适⽤于配置⽂件的格式与windows的 ini⽂件类似,
    可以包含⼀个或多个节(section)
    每个节可以有多个参数(键=值).
    ⾸先, 我们先看⼀个xxx服务器的配置⽂件

    import configparser
    
    # config = configparser.ConfigParser() # 创建对象
    #
    # config['DEFAULT'] = {  # 特殊的,默认的,其他所有的章节都含有他的内容,跟函数的类变量一样
    #     "name":"腾讯qq木马",
    #     "time":"qq更新时间",
    #     "version":"1.0"
    # }
    # config['SERVER_1'] = {
    #     "IP":"192.168.1.123",
    #     "port":"12306"
    # }
    # config['SERVER_2'] = {
    #     "IP":"192.168.1.178",
    #     "port":"12311"
    # }
    # config['SERVER_3'] = {
    #     "IP":"192.168.1.176",
    #     "port":"12312"
    # }
    #
    # # 写入到文件
    # config.write(open("qq.ini", mode="w", encoding="utf-8"))
    
    
    # 读取内容
    config = configparser.ConfigParser() # 创建对象,
    # 读取内容
    config.read("qq.ini", encoding="utf-8") # 此时我们把文件中的内容读取到config
    print(config['SERVER_1']['IP']) # 字典
    print(config['SERVER_2']['name'])
    print(config.get("SERVER_3", "IP")) # 字典
    
    for k, v in config['DEFAULT'].items():
        print(k, v)
    
    # 增删改操作:
    # 先读取. 然后修改. 最后写回⽂件
    
    # config = configparser.ConfigParser()
    # # 读取内容
    # config.read("qq.ini", encoding="utf-8") # 此时我们把文件中的内容读取到config
    
    # config['SERVER_1']['NAME'] = "哈哈哈"  # 增加
    
    # 添加⼀个章节
    # config.add_section("189-DB")
    # config["189-DB"] = {
    # "db_ip": "167.76.22.189",
    # "port": "3306",
    # "u_name": "root",
    # "u_pwd": "123456"
    # }
    
    # 修改信息
    config.set("SERVER_1", "IP", "10.10.10.168")
    # 删除章节
    config.remove_section("SERVER_2")
    # 删除元素信息
    config.remove_option("SERVER_3", "port")
    
    # 写回文件
    # config.write(open("qq.ini", mode="w", 
  • 相关阅读:
    3. Longest Substring Without Repeating Characters
    2. Add Two Numbers
    1. Two Sum
    关于LSTM核心思想的部分理解
    常用正则表达式RE(慕课网_Meshare_huang)
    安装Keras出现的问题
    win系统下如何安装xgboost,开发环境是anaconda,以及这中间需要注意的问题
    Shell基础
    关机与重启命令
    压缩与解压缩命令
  • 原文地址:https://www.cnblogs.com/yipianshuying/p/9966480.html
Copyright © 2020-2023  润新知