欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

第二十二天- 序列化 pickle json shelve

程序员文章站 2022-10-04 19:51:07
1 import pickle 2 3 4 class User: 5 def __init__(self,username,password): 6 self.username = username 7 self.password = password 8 9 10 class Client: 1 ......

 

# 序列化:存储或传输数据时,把对象处理成方便存储和传输的数据格式,这个过程即为序列化
# python中序列化的三种方案:
# 1.pickle python任意数据——》bytes写入⽂件;写好的bytes——》python的数据.
# 2.shelve 简单另类的⼀种序列化⽅案. 可以作为⼀种⼩型的数据库来使⽤
# 3.json 将字典列表转换成字符串,前后端数据交互高频使用的⼀种数据格式


# pickle:
# 写入到文件的是bytes

# pickle中的dumps可以序列化⼀个对象.loads可以反序列化⼀个对象
 1 import pickle
 2 class cat:
 3     def __init__(self,name,color):
 4         self.name = name
 5         self.color =color
 6 
 7     def chi(self):
 8         print("%s猫会吃老鼠"%(self.name))
 9 
10 c = cat("加菲","橘色")
11 # c.chi()
12 bs = pickle.dumps(c)  # 把对象转换成bytes
13 # print(bs)  # b'\x80\x03c__main__\ncat\nq\x00)\x81q\x01}q\x02(x\x04\x00\x00\x00nameq\x03x\x06\x00\x00\x00\xe5\x8a\xa0\xe8\x8f\xb2q\x04x\x05\x00\x00\x00colorq\x05x\x06\x00\x00\x00\xe6\xa9\x98\xe8\x89\xb2q\x06ub.'
14 
15 # 把bytes反序列化成对象
16 cc = pickle.loads(b'\x80\x03c__main__\ncat\nq\x00)\x81q\x01}q\x02(x\x04\x00\x00\x00nameq\x03x\x06\x00\x00\x00\xe5\x8a\xa0\xe8\x8f\xb2q\x04x\x05\x00\x00\x00colorq\x05x\x06\x00\x00\x00\xe6\xa9\x98\xe8\x89\xb2q\x06ub.')
17 cc.chi()
18 print(cc.name,cc.color)  # 加菲猫会吃老鼠  加菲 橘色

# dump load读写文件操作
# dump load ⼀个对象写读到文件
1 c = cat("加菲","橘色")
2 pickle.dump(c,open("cat.dat",mode = 'wb'))  # 把对象写到文件  pickle.dump() 注意bytes用wb模式
3 ccc = pickle.load(open('cat.dat',mode='rb'))  # 把对象读取出来  pickle.load() 注意bytes用rb模式
4 ccc.chi()  # 加菲猫会吃老鼠
5 print(ccc.name,ccc.color)  # 加菲 橘色

# pickle用list读写多个对象
 1 c1 = cat("加菲1","橘色")
 2 c2 = cat("加菲2","橘色")
 3 c3 = cat("加菲3","橘色")
 4 c4 = cat("加菲4","橘色")
 5 c5 = cat("加菲5","橘色")
 6 
 7 # lst = [c1,c2,c3,c4,c5]
 8 # f = open('cat.dat',mode='wb')
 9 # pickle.dump(lst,f)  # 把lst写到f
10 
11 f = open('cat.dat',mode='rb')
12 lis = pickle.load(f)  # 把lis从f读取出来
13 for cc in lis:
14     cc.chi()

# 应用:pickle实现注册登录
第二十二天- 序列化 pickle  json  shelve
 1 import pickle
 2 
 3 
 4 class user:
 5     def __init__(self,username,password):
 6         self.username = username
 7         self.password = password
 8 
 9 
10 class client:
11     # 注册
12     def regist(self):
13         uname = input("请输入你的账户:")
14         pwd = input("请输入你的密码:")
15         user = user(uname,pwd)  # 把uname pwd 传参到user类
16         pickle.dump(user,open("userinfo",mode='ab'))  # 把对象保存到userinfo
17         print("注册成功!")
18 
19     # 登录
20     def login(self):
21         uname = input("请输入你的账户:")
22         pwd = input("请输入你的密码:")
23         f = open('userinfo',mode='rb')  
24         while 1:
25             # 加入try except 当不存在的账户登录时 抛出错误
26             try:
27                 u = pickle.load(f)  # 从userinfo中读取出用户 
28                 if u.username == uname and u.password == pwd:
29                     print("登陆成功!")
30                     break
31             except exception as e:
32                 print("登录失败!")
33                 break
34 
35 d = client()
36 # print("注册")
37 # d.regist()
38 # d.regist()
39 # d.regist()
40 # print("登录")
41 # d.login()
42 # d.login()
43 # d.login()
view code


# shelve 就是把数据写到硬盘上.操作shelve非常的像操作字典.
1 import shelve
2 
3 d = shelve.open("test")  # 可理解成文件类型的字典
4 # d['wf'] = '汪峰'
5 d['wf'] = '王菲'
6 print(d['wf'])  # 汪峰  王菲
7 d.close()
# 存储一些复杂点的数据
 1 import shelve
 2 d = shelve.open('test')
 3 d['wf'] = {'name':'汪峰','age':47,'wife':{'name':'章子怡','hobby':'拍电影'}}
 4 print(d['wf']) # 运行结果 {'name': '汪峰', 'age': 47, 'wife': {'name': '章子怡', 'hobby': '拍电影'}}
 5 d.close()
 6 
 7 # 尝试修改
 8 d = shelve.open('test')
 9 d['wf']['wife']['name'] = '小章'
10 print(d['wf'])  # 运行结果 {'name': '汪峰', 'age': 47, 'wife': {'name': '章子怡', 'hobby': '拍电影'}}
11 d.close()
12 # 坑 由上可知 直接修改没效果 需用到 writeback
# writeback=true 可动态的把修改的信息写入到⽂件中.
1 d = shelve.open('test',writeback=true)  # 文件类型字典修改时 writeback 把修改回写到文件
2 d['wf']['wife']['hobby'] = '搓麻将'  # 修改vlue
3 d.close()
4 
5 d = shelve.open('test')
6 print(d['wf'])  # 运行结果 {'name': '汪峰', 'age': 47, 'wife': {'name': '章子怡', 'hobby': '搓麻将'}}
7 d.close()

 

 

# json 前后端交互的纽带
# json全称javascript object notation.翻译js对象简谱.
# json代码(python中的字典)
 1 wf = {
 2     "name":"汪峰",
 3     "age":18,
 4     "hobby":"上头条",
 5     "wife":{
 6         "name":'⼦怡',
 7         "age":19,
 8         "hobby":["唱歌", "跳舞", "演戏"]
 9         }
10 }
# 直接把字典转化成json字符串
import json
1 dic = {'a':'一只萝莉','b':'两只萝莉','c':'一群萝莉','d':false,'e':none}
2 s = json.dumps(dic,ensure_ascii=false)  # ensure_ascii 固定套路不转成bytes
3 print(type(s))  # <class 'str'>
4 print(s)  # {"a": "一只萝莉", "b": "两只萝莉", "c": "一群萝莉", "d": false, "e": null}
# 把json字符串转换成字典
1 s1 = '{"a": "一只萝莉", "b": "两只萝莉", "c": "一群萝莉", "d": false, "e": null}'
2 d = json.loads(s1)
3 print(d)  # {'a': '一只萝莉', 'b': '两只萝莉', 'c': '一群萝莉', 'd': false, 'e': none}
4 print(type(d))  # <class 'dict'>
# 把json写入文件
1 dic = {'a':'小萝莉','b':'大萝莉','c':'一群萝莉','d':false,'e':none,'wf':{'name':'怒放的生命','hobby':'皮裤'}}
2 f = open('loli.json',mode='w',encoding='utf-8')  # 注意:utf-8格式写入
3 json.dump(dic,f,ensure_ascii=false,indent=4)  # indent=4 缩进4格 等同tab 便于阅读
# 文件中读取json
1 f = open('loli.json',mode='r',encoding="utf-8")
2 d = json.load(f)
3 # print(d)
4 f.close()
# 把对象转换成json
第二十二天- 序列化 pickle  json  shelve
 1 class person:
 2     def __init__(self,firstname,lastname):
 3         self.firstname = firstname
 4         self.lastname = lastname
 5 
 6 p = person('尼古拉斯','赵四')
 7 
 8 # 方案一 转化的是字典
 9 s = json.dumps(p.__dict__,ensure_ascii=false)
10 print(s)  # {"firstname": "尼古拉斯", "lastname": "赵四"}
11 
12 # 方案二 自己定义函数
13 def func(obj):
14     return {
15         'firstname':obj.firstname,
16         'lastname':obj.lastname
17     }
18 
19 s = json.dumps(p,default=func,ensure_ascii=false)
20 print(s)  # {"firstname": "尼古拉斯", "lastname": "赵四"}
view code
# 函数把字典(json)转换成对象
1 s = '{"firstname": "尼古拉斯", "lastname": "赵四"}'
2 def func(dic):
3     return person(dic['firstname'],dic['lastname'])
4 
5 p = json.loads(s,object_hook=func)  # 字典转换成对象
6 
7 print(p.firstname,p.lastname)

 

# 注意.我们可以向同⼀个⽂件中写⼊多个json串.但是读不⾏.
第二十二天- 序列化 pickle  json  shelve
 1 import json
 2 lst = [{'a':1},{'b':2},{'c':3}]
 3 f = open('test.json',mode='w',encoding='utf-8')
 4 for el in lst:
 5     json.dump(el,f)
 6 f.close()
 7 # 若需要读取改用 dumps和loads  循环对每行分别处理
 8 import json
 9 lst = [{"a": 1}, {"b": 2}, {"c": 3}]
10 # 写⼊
11 f = open("test.json", mode="w", encoding="utf-8")
12 for el in lst:
13     s = json.dumps(el, ensure_ascii=true) + "\n"  # 注意dumps这里ensure_ascii是true
14     f.write(s)
15 f.close()
16 # 读取
17 f = open("test.json", mode="r", encoding="utf-8")
18 for line in f:
19     dic = json.loads(line.strip())
20     print(dic)
21 f.close()
view code

 

 

# configparser模块(参考)
# 模块用于配置⽂件格式与windows ini⽂件类似,可以包含⼀个或多个节(section)每个节可有多个参数(键=值)
# 服务器配置文件
 1 '''
 2 [default] [default]
 3 serveraliveinterval = 45
 4 compression = yes
 5 compressionlevel = 9
 6 forwardx11 = yes
 7 [[bitbucket.org bitbucket.org]]
 8 user = hg
 9 [[topsecret.server.com topsecret.server.com]]
10 port = 50022
11 forwardx11 = no
12 '''
# ⽤configparser对这样的⽂件进⾏处理
# 初始化
第二十二天- 序列化 pickle  json  shelve
 1 import configparser
 2 
 3 config = configparser.configparser()
 4 config['default'] = {
 5 "sleep": 1000,
 6  "session-time-out": 30,
 7  "user-alive": 999999
 8 }
 9 config['test-db'] = {
10  "db_ip": "192.168.17.189",
11  "port": "3306",
12  "u_name": "root",
13  "u_pwd": "123456"
14 }
15 config['168-db'] = {
16  "db_ip": "152.163.18.168",
17  "port": "3306",
18  "u_name": "root",
19  "u_pwd": "123456"
20 }
21 config['173-db'] = {
22  "db_ip": "152.163.18.173",
23  "port": "3306",
24  "u_name": "root",
25  "u_pwd": "123456"
26 }
27 f = open("db.ini", mode="w")
28 config.write(f) # 写⼊⽂件
29 f.flush()
30 f.close()
view code
# 读取文件信息
第二十二天- 序列化 pickle  json  shelve
 1 config = configparser.configparser()
 2 config.read("db.ini") # 读取⽂件
 3 print(config.sections()) # 获取到section. 章节...default是给每个章节都配备的信息
 4 print(config.get("default", "session-time-out")) # 从xxx章节中读取到xxx信息
 5 # 也可以像字典⼀样操作
 6 print(config["test-db"]['db_ip'])
 7 print(config["173-db"]["db_ip"])
 8 for k in config['168-db']:
 9  print(k)
10 for k, v in config["168-db"].items():
11  print(k, v)
12 print(config.options('168-db')) # 同for循环,找到'168-db'下所有键
13 print(config.items('168-db')) #找到'168-db'下所有键值对
14 print(config.get('168-db','db_ip')) # 152.163.18.168 get⽅法section下的key对应的value
view code
# 增删改操作
# 先读取. 然后修改. 最后写回⽂件
第二十二天- 序列化 pickle  json  shelve
 1 config = configparser.configparser()
 2 config.read("db.ini") # 读取⽂件
 3 # 添加⼀个章节
 4 # config.add_section("189-db")
 5 # config["189-db"] = {
 6 # "db_ip": "167.76.22.189",
 7 # "port": "3306",
 8 # "u_name": "root",
 9 # "u_pwd": "123456"
10 # }
11 # 修改信息
12 config.set("168-db", "db_ip", "10.10.10.168")
13 # 删除章节
14 config.remove_section("173-db")
15 # 删除元素信息
16 config.remove_option("168-db", "u_name")
17 # 写回⽂件
18 config.write(open("db.ini", mode="w"))
view code