zoukankan      html  css  js  c++  java
  • 常用模块-02

    本节主要内容:

    1. 什么是序列化

    2.pickle(重点)

    3.shelve

    4.json(重点)

    5.configparser模块

    一. 什么是序列化

      在我们储存数据或者网络传输数据的时候.需要对我们的对象进行处理.把对象处理成方便存储和传输的数据格式.

    这个过程叫序列化.不同的序列化,结果也不同.但是目的是一样的.都是为了储存和传输.

    在python中存在三种序列化的方案:

    1.pickle:可以将我们python中的任意数据类型转化成bytes并写入到文件中.同样也可以把文件中写好的bytes转换回我们

    python的数据.这个过程被称为反序列化

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

    3.json:将python中常见的字典,列表转化成字符串,是目前后端数据交互使用频率最高的一种数据格式.

    二.pickle(重点)

      pickle: 可以将我们python中的任意数据类型转化成bytes并写入到文件中.同样也可以把文件中写好的bytes转换回我们python

    的数据.这个过程被称为反序列化.

    pickle.dumps(c) & pickleloads

    import pickle
    
    class Cat:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def chi(self):
            print(self.name, "抓老鼠")
    
    c = Cat("Jerry",18)
    
    bs = pickle.dumps(c)    # 序列化一个对象.
    print(bs)   # 一堆二进制
    # b'x80x03c__main__
    Cat
    qx00)x81qx01}qx02(Xx04x00x00x00nameqx
    # 03Xx05x00x00x00Jerryqx04Xx03x00x00x00ageqx05Kx12ub.'
    cc = pickle.loads(bs)   # 把二进制反序列化成我们的对象
    cc.chi()    # 依旧是之前的对象
    # Jerry 抓老鼠

    pickle中的dumps可以序列化一个对象.loads可以反序列化一个对象.

    pickle.dump() & pickle.load()

    import pickle
    
    class Cat:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def chi(self):
            print(self.name, "抓老鼠")
    
    c = Cat("Jerry",18)
    
    f1 = open("cat",mode="wb")
    pickle.dump(c,f1)   # 写入到文件中
    f1.close()
    
    f2 = open("cat",mode="rb")
    cc = pickle.load(f2)    # 从文件中读取对象
    cc.chi()

    dump可以直接把一个对象写入到文件中,load可以从文件中读取对象

    pickle还支持多个对象的写入

    import pickle
    
    class Cat:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def chi(self):
            print(self.name, "抓老鼠")
    
    
    lst = [Cat("Jerry", 19), Cat("Tommy", 20), Cat("alpha", 21)]
    with open("cat", mode="wb") as f3:
        for el in lst:
            pickle.dump(el,f3)    # 写入到文件中
    
    with open ("cat", mode="rb") as f4:
        for i in range(len(lst)):
            cc = pickle.load(f4)    # 从文件中读取对象
            cc.chi()

    但是有的时候我们并不知道我们有多少对象需要读. 这里记住,不能一行一行的读, 因为假如要读的内容有很多怎么办?

    多以我们可以把要读的文件装在list里, 然后读取和写入都用list

    import pickle
    
    class Cat:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def chi(self):
            print(self.name, "抓老鼠")
    
    lst = [Cat("Jerry", 19), Cat("Tommy", 20), Cat("alpha", 21)]
    with open("cat.dat", mode="wb") as f3:
            pickle.dump(lst,f3)
    
    f = open("cat.dat", mode="rb")
    lst = pickle.load(f) # 读取第一次
    for el in lst:
        el.chi()

    在使用pickle的时候,记住pickle序列化的内容是二进制的内容(bytes).

    三.shelve

    shelve提供python的持久化操作. 持久化操作就是把数据写到硬盘上.在操作shelve的时候非常像操作一个字典.

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

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

    接下来我们可以储存一点复杂的数据

    s = 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当成字典来用就好了

    四.json(重点)

    json: JavaScript Object Notation   JS对象简谱

    因为json的语法格式可以完美的表⽰出⼀个对象.

    json:前后端交互的枢纽,相当于编程界的普通话.为什么大家都用json来沟通呢?因为json的语法格式可以完美的表⽰出⼀个对象.

    wf = {
     "name":"汪峰",
     "age":18,
     "hobby":"上头条",
     "wife":{
     "name":'⼦怡',
     "age":19,
     "hobby":["唱歌", "跳舞", "演戏"]
     }
    }

    在python中上面的内容叫做字典,但是在JavaScript中上面的内容被叫做json.这样的数据结构可以完美的表示出任何对象.

    并且可以完整的把对象表示出来,而且只要代码格式比较好,可读性也很强.所以大家公认用这样一种数据结构作为数据交

    互的格式.而在这之前的程序员使用一种叫做XML的东西.

    <?xml version="1.0" encoding="utf-8" ?>
    <wf>
     <name>汪峰</name>
     <age>18</age>
     <hobby>上头条</hobby>
     <wife>
     <name>⼦怡</name>
     <age>18</age>
     <hobbies>
     <hobby>唱歌</hobby>
     <hobby>跳舞</hobby>
     <hobby>演戏</hobby>
     </hobbies>
     </wife>
    
    </wf>

    以前的程序员都是用上面这样的数据进行传输的,老版本的xml在维护和处理上是非常复杂和繁琐的,而且解析比较复杂.

    1.字典==>json字符串    json字符串==>字典

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

    ensure_ascii = False 的作用是不使用ASCII来解码, 因为我们的内容中有中文

    import json
    
    s = '{"a": "女王", "b": "萝莉", "c": "小清新"}'
    dic = json.loads(s)
    print(type(dic), dic)
    # 结果:<class 'dict'> {'a': '女王', 'b': '萝莉', 'c': '小清新'}

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

    import json
    dic = {"a": "女王", "b": "萝莉", "c": "小清新"}
    with open("abc.json", mode="w", encoding="utf-8") as f:
        json.dump(dic, f, ensure_ascii=False)

    从文件中读取一个json文件

    import json
    
    with open("abc.json", mode="r", encoding="utf-8") as f:
        dic = json.load(f)
    print(dic)

    注意: 我们可以向同一个文件中写入多个json串. 但是读不行

    import json
    
    lst = [{"a": 1}, {"b": 2}, {"c": 3}]
    with open("lst.json", mode="w", encoding="utf-8") as f:
        for el in lst:
            json.dump(el,f)

    注意,此时文件中的内容是一行内容.

    {"a": 1}{"b": 2}{"c": 3}

    这在读取的时候是⽆法正常读取的. 那如何解决呢? 两套⽅案. ⽅案⼀. 把所有的内容准备好统⼀进⾏写⼊和读取.

    但这样处理, 如果数据量⼩还好. 数据量⼤的话, 就不够友好了. ⽅案⼆. 不⽤ dump. 改⽤dumps和loads. 对每⼀⾏分别进⾏处理.

    import json
    
    
    lst = [{"a": 1}, {"b": 2}, {"c": 3}]
    # 写入
    f = open("lst.json", mode="w", encoding="utf-8")
    for el in lst:
        s = json.dumps(el,ensure_ascii=True) + "
    "
        f.write(s)
    f.close()
    
    # 读取
    f = open("lst.json", mode="r",encoding="utf-8")
    for line in f:
        dic = json.loads(line.strip())
        print(dic)
    f.close()

    五.configparser模块

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

    ⾸先, 我们先看⼀个xxx服务器的配置⽂件

    [DEFAULT] [DEFAULT]
    ServerAliveInterval = 45
    Compression = yes
    CompressionLevel = 9
    ForwardX11 = yes
    [[bitbucket.org bitbucket.org]] User
    = hg
    [[topsecret.server.com topsecret.server.com]] Port
    = 50022 ForwardX11 = no

     我们用configparser就可以对这样的文件进行处理,首先是初始化

    import configparser
    config = configparser.ConfigParser()
    config['DEFAULT'] = {
     "sleep": 1000,
     "session-time-out": 30,
     "user-alive": 999999
    }
    config['TEST-DB'] = {
     "db_ip": "192.168.17.189",
     "port": "3306",
     "u_name": "root",
     "u_pwd": "123456"
    }
    config['168-DB'] = {
     "db_ip": "152.163.18.168",
     "port": "3306",
     "u_name": "root",
     "u_pwd": "123456"
    }
    config['173-DB'] = {
     "db_ip": "152.163.18.173",
     "port": "3306",
     "u_name": "root",
     "u_pwd": "123456"
    }
    f = open("db.ini", mode="w")
    config.write(f) # 写⼊⽂件
    f.flush()
    f.close()

    读取文件信息:

    config = configparser.ConfigParser()
    config.read("db.ini") # 读取⽂件
    print(config.sections()) # 获取到section. 章节...DEFAULT是给每个章节都配备的信息
    print(config.get("DEFAULT", "SESSION-TIME-OUT")) # 从xxx章节中读取到xxx信息
    # 也可以像字典⼀样操作
    print(config["TEST-DB"]['DB_IP'])
    print(config["173-DB"]["db_ip"])
    for k in config['168-DB']:
     print(k)
    for k, v in config["168-DB"].items():
     print(k, v)
    print(config.options('168-DB')) # 同for循环,找到'168-DB'下所有键
    print(config.items('168-DB')) #找到'168-DB'下所有键值对
    print(config.get('168-DB','db_ip')) # 152.163.18.168 get⽅法Section下的
    key对应的value

     增删改操作:

    # 先读取. 然后修改. 最后写回⽂件
    config = configparser.ConfigParser()
    config.read("db.ini") # 读取⽂件
    # 添加⼀个章节
    # config.add_section("189-DB")
    # config["189-DB"] = {
    # "db_ip": "167.76.22.189",
    # "port": "3306",
    # "u_name": "root",
    # "u_pwd": "123456"
    # }
    # 修改信息
    config.set("168-DB", "db_ip", "10.10.10.168")
    # 删除章节
    config.remove_section("173-DB")
    # 删除元素信息
    config.remove_option("168-DB", "u_name")
    # 写回⽂件
    config.write(open("db.ini", mode="w"))
  • 相关阅读:
    20155322 2016-2017-2 《Java程序设计》第7周学习总结
    高级sed编程
    正则表达式
    实验十二:kvm环境下qemu-kvm创建虚拟机之间的网络配置
    实验十一:了解qemu-kvm的显示选项参数
    实验十:在kvm下创建winxp虚拟机
    实验九:第二个虚拟机的创建(标准选项)
    实验八:kvm环境搭建并创建第一台cirrOS虚拟机
    sed和gawk
    在脚本中添加颜色
  • 原文地址:https://www.cnblogs.com/af1y/p/9964983.html
Copyright © 2011-2022 走看看