常用模块-02
一:什么是序列化
在我们储存数据或网络传输数据的时候,我们需要对我们的对象进行处理,把对象处理成方便储存和传输的数据格式。
这个过程就叫序列化。不同的序列化,结果不同,但是目的是一样的,都是为了存储和传输。、
在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 catch(self):
print(self.name,'抓老鼠')
c = Cat('汤姆',56)
bs = pickle.dumps(c) # 序列化对象
print(bs)
cc = pickle.loads(bs) # 把二进制反序列化成对象
cc.catch()
pickle中的dumps可以序列化一个对象,loads可以反序列化一个对象,使用dump还可以直接把对象写入到文件中
f = open('filepath',mode='wb')
pickle.dump(c,f)
f.close()
f = open('filepath',mode='rb',)
cc = pickle.load(f)
cc.catch()
pickle还支持多个对象的写出。
lst = [Cat('汤姆',21),Cat('杰瑞',20),Cat('alex',34)]
f = open('filepath',mode='wb')
for el in lst:
pickle.dump(el,f)
f.close()
f = open('filepath',mode='rb')
for i in range(len(lst)):
cc = pickle.load(f)
cc.catch()
这样写并不好,因为在读的时候,并不知道有多少对象要读。 * 注意:不能一行一行的读,真的要写入或读取多个内容时,把内容装进
list里,然后读和去都用list去操作。
lst = [Cat('汤姆',21),Cat('杰瑞',20),Cat('alex',34)]
f = open('filepath',mode='wb')
pickle.dump(lst,f)
f = open('filepath',mode='rb')
ll = pickle.load(f)
for el in ll:
el.catch()
注:pickle序列化的内容是二进制的内容(bytes)
三:shevel
shelve提供python的持久化操作,就是把数据写到硬盘上,在操作shelve的时候非常像在操作一个字典。
import shelve
shelf = shelve.open('sylar')
# shelf['jay'] = '周杰伦'
print(shelf['jay'])
shelf.close()
储存复杂数据
s = shelve.open('sylar')
s['jay'] = {'name':'阮小二','age':25,'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['阮小二'] = '立地太岁'
s['活阎罗'] = '阮小五'
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()
四:json(重点)
json 是我们前后端交互的枢纽,相当于编程界的普通话,大家相互沟通用json。因为json的语法格式可以完美的
表示出一个对象。json全程:javascript object notation,翻译过来叫js对象简谱。
wf = {
'name':'汪峰',
'age':45,
'hobby':'搞事情',
'wife':{
'name':'章子怡',
'age':18,
'hobby':['演戏','扔皮鞋']
}
}
在python中这叫字典,但在javascript里这叫做json。用这样的数据结构可以完美的表示出任何对象,并且可以把对象完美的表示
出来,只要代码格式比较好,可读性就很强,所以大家公认这一种数据结构作为数据交互的格式。
如何把python字典转成json格式的字符串
import json
dic = {'a':'宋江','b':'卢俊义','c':'吴用'}
s = json.dumps(dic) # 把字典转换成json字符串
print(s)
结果:{"a": "\u5b8b\u6c5f", "b": "\u5362\u4fca\u4e49", "c": "\u5434\u7528"}
如何把样的结果处理成中文,在dumps的时候给出另一个参数ensure_ascii=False
import json
dic = {'a':'宋江','b':'卢俊义','c':'吴用'}
s = json.dumps(dic,ensure_ascii=False) # 把字典转换成json字符串
print(s)
把前端传来的json字符串转化成字典
import json
s = '{"a":"1","b":"2","c":"3"}'
dic = json.loads(s)
print(type(dic),dic)
json也可以像pickle一样把序列化写入到文件中
import json
dic = {"a":"1","b":"2","c":"3"}
f = open('test.json',mode='w',encoding='utf-8')
json.dump(dic,f,ensure_ascii=False) # 把对象打散成json写入到文件中
f.close()
# 读取文件
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()
注:文件中是一行的格式({"a": 1}{"b": 2}{"c": 3})
这样在读取的时候时无法正常读取的,两套解决方案。
第一套:把所有内容准备好统一进行写入和读取,这样可以处理数据量小的问题,数据量大了比较麻烦。
第二套:不用dump,改用dumps写入,手动加"\n"换行和loads,对每一行分别进行处理。
第二套方案:
import json
lst = [{"a":"特洛伊木马"},{"b":"城堡"},{"c":"天黑"}]
# 写入
f = open('test.json',mode='w',encoding='utf-8')
for el in lst:
s = json.dumps(el,ensure_ascii=False) + '\n' # 手动写入换行
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()
五:configparser 模块
该模块适用于配置文件的格式与windsws ini文件类型,可以包含多个节(section)每个节可以有多个参数(键=值)
import configparser
config = configparser.ConfigParser()
config['DEFAULT'] = {
'sleep':1000,
'session-time-out':30,
'user-alive':9999
}
config['TEST-DB'] = {
'db_ip':'152.163.18.168',
'port':'3306',
'u_name':'root',
'u_pwd':'1234'
}
config['168-DB'] = {
'db_ip':'152.168.10.11',
'port':'3306',
'u_name':'root',
'u_pwd':'9630'
}
config['163-DB'] = {
'db_ip':'136.125.63.21',
'port':'3306',
'u_name':'root',
'u_pwd':'7894'
}
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['163-DB']['db_ip'])
for k in config['163-DB']:
print(k)
for k,v in config['163-DB'].items():
print(k,v)
print(config.options('163-DB')) # 同for循环,找到'163-DB'下所有键
print(config.items('163-DB')) # 找到'163-DB'下所有键值对
print(config.get('163-DB','db_ip')) # get方法Setion下的key对应的value
增删改查
# 先读取,然后修改,最后写回文件
import configparser
config = configparser.ConfigParser()
config.read('db.ini') # 读取文件
# 添加章节
config.add_section('178-DB')
config['178-DB'] = {
'db_ip':'156.654.236.32',
'port':'3306',
'u_name':'root',
'u_pwd':'0000'
}
# 修改信息
config.set('163-DB','db_ip','10.11.12.13')
# 删除章节
config.remove_section('178-DB')
# 删除元素信息
config.remove_option('163-DB','u_name')
# 写回文件
config.write(open('db.ini',mode='w'))