python json模块和pickle模块

用于序列化的两个模块

  • 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>
posted @ 2017-11-15 16:37  黄骁瀚cerny  阅读(278)  评论(0编辑  收藏  举报