Python课程回顾(day19)
常用模块2
1.json序列化与反序列化
在学习今天的内容之前我们首先要了解:
01.什么是序列化
序列化其实可以用一句话概括,就是我们把内存中的数据存储或传输的过程就称之为序列化,在python中这种过程叫做picking。
02.为什么要用序列化
首先我们要知道,一个程序或软件的运行就是在处理一系列的状态,而随着这个状态的不断变化,它会以各种各样的结构或形式存储到内存中,而内存是无法永久保存的,如果恰巧在这个时候电脑故障或者断电,那么我们之前所做的一切都将会被清空。而如果我们在断电或故障之前将我们的数据永久的存储到硬盘内,那么我们下次再启动程序的时候,程序就会基于上次的执行而执行,这个就称之为序列化。而在序列化之后,不仅可以将数据永久的存储到硬盘,还可以通过网络传输到别的机器上,如果收发的双方约定好使用同一种序列化格式,那么便打破了平台语言的限制,就实现了跨平台的各种交互。
03.json序列化与反序列化的具体应用
import json # # 1.序列化之json.dumps() # 会将括号内的任何类型转成json所能识别的字符串,json格式全部都是双引号 # # data = {'name': 'klf', 'age': 18} # res = json.dumps(data) # with open('a.json', mode='wt', encoding='utf-8') as f: # f.write(res) # 存储时json会将data内的所有单引号变为双引号(各平台通用格式) # # 2.反序列化之json.loads # x = "[1, true, null, false]" # res = json.loads(x) # 将true,false其他平台上的关键字反序列化为python可以识别的关键字 # print(res) # 3.序列化之json.dump # data = {'name': 'klf', 'age': 18} # with open('a1.json', 'wt', encoding='utf-8') as f: # json.dump(data, f) # 使用dump可以更简洁的将数据以json格式写入文件 # dump括号内的参数一个是数据,一个是文件名(会自动调用f.write) # 4.反序列化之json.load # with open('a1.json', 'rt', encoding='utf-8') as f1: # print(json.load(f1)) # 使用load可以更简洁的将数据以反序列化格式读取文件 # json.load括号内的参数本质就是调用了f1.read的功能
总结:就目前来说,我们使用json可以更快更简洁的将数据以各个平台通用的格式进行写入与读取,但json也不是万能的
它能识别python内的数据类型是有限的,遇到python内部独有的数据类型它就不能识别了
可以识别的数据类型:(dict,list,str,None,True,False,int,float)
不可识别的数据类型:(set,tuple,或python独有的等等)
2.pickle序列化与反序列化
import pickle # 1.序列化之pickle.dumps # s = {1, 2, 3, 4} # with open('a.pkl', 'wb') as f: # pickle是以bytes类型进行序列与反序列化的,所以以b模式写入 # res = pickle.dumps(s) # 反序列化结果赋值给res # print(res, type(res)) # f.write(res) # 2.反序列化之pickle.loads # with open('a.pkl', 'rb') as f: # 再次强调pickle是以字节类型进行的序列与反序列化,模式一定要b # data = f.read() # res = pickle.loads(data) # 反序列化结果赋值给res # print(res) # 3.序列化之pickle.dump # s = {1, 2, 3} # with open('a1.pkl', 'wb') as f: # b模式 # pickle.dump(s, f) # 过程等同于json.dump # with open('a1.pkl', 'rb') as f: # b模式 # res = pickle.load(f) # 过程等同于json.load # print(res)
总结:特点:pickle与json的根本区别就在于pickle是可以识别python内所有数据类型的,不过它会将这些数据类型以“Bytes”类型进行序列化与反序列
缺点:pickle也只能识别python内的数据类型,其他平台的数据类型是识别不了的,所以相比较起json识别不了的数据类型它是有优势的,
但set与tuple也是不常用的数据类型,所以整体来说pickle不常用。
3.shevle模块
import shelve # # info1 = {'age': 18, 'height': 180, 'weight': 80} # info2 = {'age': 73, 'height': 150, 'weight': 125} # # d = shelve.open('db.shv') # d['egon'] = info1 # d['alex'] = info2 # 写入完成后会出现三个不同的文件,不必管它,在不同的平台会产生相应的且不同的文件 # d.close() # 注意关闭文件!!!!! # f = shelve.open('db.shv') # print(f['egon']) # print(f['alex']) # 直接根据之前存储的变量名来读取即可 # f.close() # 注意关闭文件!!!!! # f = shelve.open('db.shv', writeback=True) # writeback的默认值为False,不修改为True则不能修改文件内容 # f['egon']['age'] = 123 # 可以通过key来修改值 # f['alex']['height'] = 150 # 可以通过key来修改值 # f.close() # 注意关闭文件!!!!!
4.xml模块
import xml.etree.ElementTree as ET tree = ET.parse('a.xml') # 解析文件赋值给一个对象(拿到整棵树) root = tree.getroot() # 拿到树根 # 查找的三种方式一之iter: # res = root.iter('name') # 会在整个树形结构进行查找,而且查找到所有对应值 # print(res) # 得到一个迭代器对象 # for item in res: # print('='*50) # xml中查找每一个元素都对应有三个特征 # print(item.tag) # tag = 标签名(即镜像对应的两个名称,带/的标签起闭合作用) # print(item.attrib) # attrib = 属性(放在标签后的描述,可以不写) # print(item.text) # text = 文本(即标签的值) # 查找的三种方式一之find: # res = root.find('ahead') # 只能在当前元素的下一级开始查找,并且只找到一个就结束 # res1 = res.find('name') # 可以拿到当前层级再次进行具体查找,但只能找当前层级下的分支,也是只找到一个就结束查找 # print(res1.text) # 查找的三种方式一之findall: # res = root.findall('') # 只能在当前元素的下一级开始查找,找到全部后结束 # for item in res: # print(item.tag) # print(item.attrib) # print(item.text)
# 使用for循环修改xml文件里的值
tree = ET.parse('b.xml')
root = tree.getroot()
for year in root.iter('year'):
year.text = str(int(year.text) + 1) # 由于文件里读取的数据是字符串类型所以要转换成int类型相加
year.attrib = {'x':'y'} # 添加属性要按照字典形式添加,且必须都是字符串
# 但是写回文件要以str类型所以还要转换
tree.write('c.xml')
# 在year大于2020年的主标签内添加新的标签
import xml.etree.ElementTree as ET
tree = ET.parse('b.xml')
root = tree.getroot()
for country in root.iter('year'):# 使用for循环增加与删除
year = country.find('year') # 找到每个country下的year
if int(year.txt) > 2020: # 判断
ele = ET.Element('egon') # 增加新的标签(关键字Element)
ele.attrib = {'name': 'alex'} # 为标签增添新的属性
ele.text = 'beautiful' # 增加文本内容
country.append(ele) # 使用append将新标签添加到当前标签内
country.remove('year') # 使用remove删除某个标签
tree.write('b.xml') # 写回源文件
5.configparser模块
import configparser # 解析配置文件 config = configparser.ConfigParser() config.read('my.ini') secs = config.sections() # 将所有标题全部取出 print(secs) print(config.options('klf')) # 将文件内标题的option全部取出 res = config.get('klf', 'age') # get括号内需要传入标题与标题下的option就可以将option的值取出 res1 = config.getint('klf', 'age') # getint会将取出的值转换成int类型 config.getfloat() # 转换成浮点型 config.getboolean() # 转换成布尔类型