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", 
原文地址:https://www.cnblogs.com/yipianshuying/p/9966480.html