json,pickle,shelve模块,xml处理模块
常用模块学习—序列化模块详解
-
什么叫序列化?
- 序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes。
-
为什么要序列化?
- 你打游戏过程中,打累了,停下来,关掉游戏、想过2天再玩,2天之后,游戏又从你上次停止的地方继续运行,你上次游戏的进度肯定保存在硬盘上了,是以何种形式呢?游戏过程中产生的很多临时数据是不规律的,可能在你关掉游戏时正好有10个列表,3个嵌套字典的数据集合在内存里,需要存下来?你如何存?把列表变成文件里的多行多列形式?那嵌套字典呢?根本没法存。所以,若是有种办法可以直接把内存数据存到硬盘上,下次程序再启动,再从硬盘上读回来,还是原来的格式的话,那是极好的。
data = { 'roles':[ {'role':'monster','type':'pig','life':50}, {'role':'hero','type':'关羽','life':80}, ] } #将数据写入game_status文件 #f = open("game_status","w") #f.write(str(data)) #将数据从game_status文件读出来 f = open("game_status","r") d = f.read() d = eval(d) print(d['roles']) #把内存数据转成字符,叫序列化 #把字符转成内存数据,叫反序列化
-
用于序列化的两个模块:
-
-
json,用于字符串 和 python数据类型间进行转换
-
pickle,用于python特有的类型 和 python的数据类型间进行转换
-
常用模块学习—序列化json模块详解
Json模块提供了四个功能:
-
dumps(
将数据通过特殊的形式转换为只有python语言认识的字符串
)(用于将dict类型的数据转成str) -
dump(
将数据通过特殊的形式转换为只有python语言认识的字符串,并写入文件
)(用于将dict类型的数据转成str,并写入到json文件中) -
loads(将str类型的数据转换成dict)
-
load(用于从json文件中读取数据)
import json #1、 data = { 'roles':[ {'role':'monster','type':'pig','life':50}, {'role':'hero','type':'关羽','life':80}, ] } #d = json.dumps(data) #dumps里存一个值 #print(d,type(d)) f = open("test.json","w") #json格式的文件,以json为拓展名 json.dump(data,f) #转入字符并写入文件。 #dump里存两个值 #2、 data = { 'roles':[ {'role':'monster','type':'pig','life':50}, {'role':'hero','type':'关羽','life':80}, ] } d = json.dumps(data) #仅转成字符串 d2 = json.loads(d) print(d2['roles']) #结果为:[{'role': 'monster', 'type': 'pig', 'life': 50}, {'role': 'hero', 'type': '关羽', 'life': 80}] #3、从文件中加载回来 # data = { # 'roles':[ # {'role':'monster','type':'pig','life':50}, # {'role':'hero','type':'关羽','life':80}, # ] # } f = open("test.json","r") data = json.load(f) print(data['roles']) #结果为:[{'role': 'monster', 'type': 'pig', 'life': 50}, {'role': 'hero', 'type': '关羽', 'life': 80}] f.close() #只是把数据类型转成字符串存到内存里的意义? #json.dumps json.loads #1、把你的内存数据 通过网络 共享给远程其他人(硬盘或网络传输时只能接受bytes ) #2、定义了不同编程语言之间的交互规则 #纯文本 缺点:不能共享复杂的数据类型 #xml 缺点:占的空间大,效率低 #json 优点:简单,占的空间小,可读性好
import json #dump 多次 f = open("json_file","w",encoding="utf-8") d = {'name':'alex','age':22} l = [1,2,3,4,'rain'] json.dump(d,f) json.dump(l,f) # load 多次 f = open("json_file", "r", encoding="utf-8") json.load(f) ''' raise JSONDecodeError("Extra data", s, end) json.decoder.JSONDecodeError: Extra data: line 1 column 28 (char 27) ''' #JSONDecodeError,json反序列化错误 #为了避免各种不必要的问题,建议不要使用多次dump
常用模块学习—序列化pickle模块详解
-
Pickle模块提供了四个功能:
-
dumps(
将数据通过特殊的形式转换为只有python语言认识的字符串
) -
dump(
将数据通过特殊的形式转换为只有python语言认识的字符串,并写入文件
) -
loads(
将数据通过特殊的形式转换为所有程序语言都认识的字符串
) -
load(
将数据通过特殊的形式转换为只有python语言认识的字符串,并写入文件
)
-
import pickle ''' d = {'name':'alex','age':22} l = [1,2,3,4,'rain'] #pk = open("data.pkl","w") pk = open("data.pkl","wb") #二进制格式写 #print(pickle.dumps(d)) #结果为:b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x04\x00\x00\x00alexq\x02X\x03\x00\x00\x00ageq\x03K\x16u.' #pickle.dump(d,pk) #结果为:#TypeError: write() argument must be str, not bytes pickle.dump(d,pk) ''' #取出来 f = open("data.pkl","rb") #二进制格式读 d = pickle.load(f) print(d) #结果为:{'name': 'alex', 'age': 22} #与json一样,不能多次dump和load多次;
import pickle,json #函数 def sayhi(): print('dddd') pickle.dumps(sayhi) json.dumps(sayhi) #结果为:raise TypeError(f'Object of type {o.__class__.__name__} ' TypeError: Object of type function is not JSON serializable ''' 小结: json 能序列化的数据类型只支持 str, int, tuple, list, dict 支持跨平台使用 pick 能序列化的数据类型支持python里的所有的数据类型 只能在Python里使用 '''
常用模块学习—序列化shelve模块详解
-
shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式。
import shelve #序列化 f = shelve.open('shelve_test') names = ["alex","rain","test"] info = {'name':'alex','age':22} f["name"] = names #持久化列表 f['info_dic'] = info f.close() #反序列化 d = shelve.open('shelve_test') print(d) #结果为:<shelve.DbfilenameShelf object at 0x00000275FCCC3160> print(d['name']) #结果为:['alex', 'rain', 'test'] print(d['info_dic']) #结果为:{'name': 'alex', 'age': 22} print(d.keys()) #结果为:KeysView(<shelve.DbfilenameShelf object at 0x0000029DA6D03390>) print(list(d.keys())) #结果为:['name', 'info_dic'] print(list(d.items())) #结果为:[('name', ['alex', 'rain', 'test']), ('info_dic', {'name': 'alex', 'age': 22})] print(d.get('name')) #结果为:['alex', 'rain', 'test'] print(d.get('info_dic')) #结果为:{'name': 'alex', 'age': 22} #修改 print(d['name']) #结果为:['alex', 'rain', 'test'] d['name'] = ['alex', 'Rain Wang', 'test'] print(d['name']) #结果为:['alex', 'rain', 'test'] d.close() #del d['test'] #还可以删除
常用模块学习—xml处理模块详解
-
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
import xml.etree.ElementTree as ET #as 起别名 tree = ET.parse('xml test') #open root = tree.getroot() #相当于f.seek(0) #print(dir(root)) #结果为:['__class__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'attrib', 'clear', 'extend', 'find', 'findall', 'findtext', 'get', 'getchildren', 'getiterator', 'insert', 'items', 'iter', 'iterfind', 'itertext', 'keys', 'makeelement', 'remove', 'set', 'tag', 'tail', 'text'] #print(root.tag) #结果为:data #遍历xml文档 for child in root: print('---------',child.tag, child.attrib) for i in child: print(i.tag,i.text) ''' 结果为: --------- country {'name': 'Liechtenstein'} rank 2 year 2008 gdppc 141100 neighbor None neighbor None --------- country {'name': 'Singapore'} rank 5 year 2011 gdppc 59900 neighbor None --------- country {'name': 'Panama'} rank 69 year 2011 gdppc 13600 neighbor None neighbor None ''' #只遍历year 节点 for node in root.iter('year'): print(node.tag,node.text) #结果为: # year 2008 # year 2011 # year 2011
import xml.etree.ElementTree as ET #as 起别名 tree = ET.parse('xml test') #open root = tree.getroot() #相当于f.seek(0) #修改 # for node in root.iter('year'): # new_year = int(node.text) + 1 # node.text = str(new_year) # node.set("attr_test","yes") # # tree.write("xml test") #向文件中循环写入数据 #删除node for country in root.findall('country'): rank = int(country.find('rank').text) if rank > 50: root.remove(country) tree.write('output.xml')
#xml test <data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year attr_test="yes">2009</year> <gdppc>141100</gdppc> <neighbor direction="E" name="Austria" /> <neighbor direction="W" name="Switzerland" /> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year attr_test="yes">2012</year> <gdppc>59900</gdppc> <neighbor direction="N" name="Malaysia" /> </country> <country name="Panama"> <rank updated="yes">69</rank> <year attr_test="yes">2012</year> <gdppc>13600</gdppc> <neighbor direction="W" name="Costa Rica" /> <neighbor direction="E" name="Colombia" /> </country> <state> <name>德州</name> <population>德州</population> </state> </data>
#output.xml <data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year attr_test="yes">2009</year> <gdppc>141100</gdppc> <neighbor direction="E" name="Austria" /> <neighbor direction="W" name="Switzerland" /> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year attr_test="yes">2012</year> <gdppc>59900</gdppc> <neighbor direction="N" name="Malaysia" /> </country> <state> <name>德州</name> <population>德州</population> </state> </data>
常用模块学习—自动创建 xml 文档
import xml.etree.ElementTree as ET new_xml = ET.Element("namelist") #创建namelist节点 name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"}) age = ET.SubElement(name,"age",attrib={"checked":"no"}) sex = ET.SubElement(name,"sex") sex.text = '33' name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"}) age = ET.SubElement(name2,"age") age.text = '19' et = ET.ElementTree(new_xml) #生成文档对象 et.write("test.xml", encoding="utf-8",xml_declaration=True) ET.dump(new_xml) #打印生成的格式
<?xml version='1.0' encoding='utf-8'?> <namelist> <name enrolled="yes"> <age checked="no" /> <sex>33</sex></name> <name enrolled="no"> <age>19</age></name> </namelist>