用于序列化的两个模块
- json,用于字符串 和 python数据类型间进行转换
- pickle,用于python特有的类型 和 python的数据类型间进行转换
Json模块提供了四个功能:dumps、dump、loads、load
pickle模块提供了四个功能:dumps、dump、loads、load
dump()函数接受一个文件句柄和一个数据对象作为参数,把数据对象以特定的格式保存 到给定的文件中。当我们使用load()函数从文件中取出已保存的对象时,pickle知道如何恢复这些对象到它们本来的格式。
dumps()函数执行和dump() 函数相同的序列化。取代接受流对象并将序列化后的数据保存到磁盘文件,这个函数简单的返回序列化的数据。
loads()函数执行和load() 函数一样的反序列化。取代接受一个流对象并去文件读取序列化后的数据,它接受包含序列化后的数据的str对象, 直接返回的对象。
示例:
ps1: 把一个字典,写入到文件中
1 dic = '{"name": "alex"}' 2 f = open("hello", "w") 3 f.write(dic)
执行结果:
会生成一个hello文件
1 {"name": "alex"}
ps2: 读取文件方法,把字典转成字符串
1 f_read=open("hello","r") #读取文件 2 data=f_read.read() 3 print(type(data)) 4 data=eval(data) #字典转成字符串(eval的使用方法) 5 print(data["name"])
执行结果:
1 <class 'str'> 2 alex
json模块方法:
ps1: 把字典转换成json形式的字符串写入文件中 (两种方法效果一样,只是写法不同而已)
方法一:推荐用这种方法
1 #1、把字典转换成json形式的字符串写入文件中 2 import json 3 dic = {'name': 'alex'} 4 dic = json.dumps(dic) 5 f = open("hello", "w") 6 f.write(dic)
方法二:
1 import json 2 dic = {'name': 'alex'} 3 f = open("hello", "w") 4 dic = json.dump(dic, f)
执行结果:
会生成一个hello的文件,并写入内容:
1 {"name": "alex"}
#----------------json------------------序列化(重点,必须掌握)
ps2: 把文件中json类型的字符串读取出来转换成字典
方法一:推荐用这种方法
1 #把文件中json类型的字符串读取出来转换成字典 2 import json 3 f = open('hello','r') 4 f = json.loads(f.read()) 5 print(f) 6 print(type(f))
方法二:
1 import json 2 f = open('hello','r') 3 f = json.load(f) #不常用这种方法 4 print(f) 5 print(type(f))
执行结果:
1 {'name': 'alex'} 2 <class 'dict'> #查看类型
注意知识点:
示例一:
1 import json 2 #dct="{'1':111}"#json 不认单引号 3 #dct=str({"1":111})#报错,因为生成的数据还是单引号:{'one': 1} 4 5 dct='{"1":"111"}' 6 print(json.loads(dct)) 7 8 #conclusion: 9 # 无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads
示例二:
先创建一个json_test文件,写入内容
1 {"name":"alvin"} #只要符合json规范就可以把值取出来。 另一种示例:{'name':"alvin"} #如果是'name' 的值是单引号就会报错。
再去取值
1 import json 2 3 with open("Json_test","r") as f: #双引号可以直接把值取出来 4 data=f.read() 5 data=json.loads(data) 6 print(data["name"])
执行结果:
1 alvin
json的dumps,loads,dump,load功能总结:
json.dumps(x) 把python的(x)原对象转换成json字符串的对象,主要用来写入文件。
json.loads(f) 把json字符串(f)对象转换成python原对象,主要用来读取文件和json字符串
json.dump(x,f) 把python的(x)原对象,f是文件对象,写入到f文件里面,主要用来写入文件的
json.load(file) 把json字符串的文件对象,转换成python的原对象,只是读文件
pickle模块:(不常用这个模块)
#---------------pickle---------------序列化
ps1: pickle转换后的结果是bytes(字节)
1 import pickle 2 3 dic = {'name': 'alvin', 'age': 23, 'sex': 'male'} 4 print(type(dic)) # <class 'dict'> 5 6 j = pickle.dumps(dic) 7 print(type(j)) # <class 'bytes'>
执行结果:
1 <class 'dict'> #字典类型 2 <class 'bytes'> #bytes类型
ps2:
1 import pickle 2 3 dic = {'name': 'alvin', 'age': 23, 'sex': 'male'} 4 j = pickle.dumps(dic) 5 f = open('序列化对象_pickle', 'wb') #注意是w是写入str,wb是写入bytes,j是'bytes' 6 f.write(j) #等价于pickle.dump(dic,f) 7 f.close()
执行结果:
生成一个序列化对象_pickle文件,文件内容如下:
1 �}q (X ageqKX sexqX maleqX nameqX alvinqu. #生成一个不可读的文件,但计算机可以解析出来
ps3: 反序列化
1 import pickle 2 3 f = open('序列化对象_pickle', 'rb') 4 data = pickle.loads(f.read()) # 等价于data=pickle.load(f) 5 print(data['age'])
执行结果:
1 23 #读出里面的结果
Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。
八、shelve模块
shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型
ps1:
1 #添加键值对到文件中,会生成三个文件,并写入字典内容 2 3 import shelve 4 5 f = shelve.open(r'shelve1') # 目的:将一个字典放入文本 f={} 6 f['stu1_info']={'name':'alex','age':'18'} 7 f['stu2_info']={'name':'alvin','age':'20'} 8 f['school_info']={'website':'oldboyedu.com','city':'beijing'} 9 f.close()
执行结果:
会生成三个文件:shelvel.dat,shelve1.dir,shelve1.bak,其中shelvel.bak中内容如下:
1 'stu1_info', (0, 49) #生成只有计算机能识别的语言 2 'stu2_info', (512, 50) 3 'school_info', (1024, 67)
ps2:取出age的值
1 import shelve 2 3 f = shelve.open(r'shelve1') 4 print(f.get('stu1_info')['age']) #取出age的值 5 print(f.get('stu2_info')['age'])
执行结果:
1 18 2 20
九、xml模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
xml的格式如下,就是通过<>节点来区别数据结构的:
1 <?xml version="1.0"?> 2 <data> #根 3 <country name="Liechtenstein"> #节点 4 <rank updated="yes">2</rank> 5 <year>2008</year> 6 <gdppc>141100</gdppc> 7 <neighbor name="Austria" direction="E"/> 8 <neighbor name="Switzerland" direction="W"/> 9 </country> 10 <country name="Singapore"> #节点 11 <rank updated="yes">5</rank> 12 <year>2011</year> 13 <gdppc>59900</gdppc> 14 <neighbor name="Malaysia" direction="N"/> 15 </country> 16 <country name="Panama"> #节点 17 <rank updated="yes">69</rank> 18 <year>2011</year> 19 <gdppc>13600</gdppc> 20 <neighbor name="Costa Rica" direction="W"/> 21 <neighbor name="Colombia" direction="E"/> 22 </country> 23 </data> 24 25 xml数据
xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:
1 import xml.etree.ElementTree as ET 2 3 tree = ET.parse("xmltest.xml") 4 root = tree.getroot() 5 print(root.tag) 6 7 #遍历xml文档 8 for child in root: 9 print(child.tag, child.attrib) 10 for i in child: 11 print(i.tag,i.text) 12 13 #只遍历year 节点 14 for node in root.iter('year'): 15 print(node.tag,node.text)
#执行结果:
year 2008
year 2011
year 2011 16 #--------------------------------------- 17 18 import xml.etree.ElementTree as ET 19 20 tree = ET.parse("xmltest.xml") 21 root = tree.getroot() 22 23 #修改 24 for node in root.iter('year'): 25 new_year = int(node.text) + 1 #2008+1=2009 26 node.text = str(new_year) 27 node.set("updated","yes") #修改通过set,加个属性yes 28 29 tree.write("xmltest.xml") 30 31 #执行结果:
会生成一个新的xmltest.xml文件,内容中会添加
<year updated="yes">2009</year> #年份+1,加个yes属性
32 #删除node 33 for country in root.findall('country'): #通过对country进行遍历 34 rank = int(country.find('rank').text) #再用find找到rank 35 if rank > 50: #再判断>50的值 36 root.remove(country) #再用remove删除 37 38 tree.write('output.xml') #写到一个新文件中
#执行结果:
自己创建xml文档:
1 import xml.etree.ElementTree as ET #as后面的ET是前面的类的别名,名称随便取 2 3 4 new_xml = ET.Element("namelist") 5 name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"}) 6 age = ET.SubElement(name,"age",attrib={"checked":"no"}) 7 sex = ET.SubElement(name,"sex") 8 sex.text = '33' 9 name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"}) 10 age = ET.SubElement(name2,"age") 11 age.text = '19' 12 13 et = ET.ElementTree(new_xml) #生成文档对象 (记住重点) 14 et.write("test.xml", encoding="utf-8",xml_declaration=True) (记住重点) 15 16 ET.dump(new_xml) #打印生成的格式 17 18 创建xml文档
执行结果:
会生成一个test.xml的文件,文件内容如下:
1 <?xml version='1.0' encoding='utf-8'?> 2 3 <namelist> 4 <name enrolled="yes"> 5 <age checked="no" /> 6 <sex>33</sex> 7 </name> 8 <name enrolled="no"> 9 <age>19</age> 10 </name> 11 </namelist>