一. 各种序列化模块
一. pickle 模块
pickle是一个用来序列化的模块
序列化是什么?
指的是将内存中的数据结构转化为一种中间格式, 并储存到硬盘上,
反序列化?
将硬盘上存储的中间格式数据在还原为内存中的数据结构
为什么要序列化?
就是为了将数据持久储存
之前学过的文件也能完成持久化存储, 但是操作起来非常麻烦
pickle模块的主要功能
dump load dumps loads
dump 是序列化. load是反序列化
不带s的是帮你封装好 write 和 read 的, 它更加方便
load 函数可以多次执行, 每次load都是往后再读一个对象, 如果没有了就抛出异常 Ran out of input
示例:
# pickle支持python中所有的数据类型
user = {'name':name , 'password':password , 'height':height , 'hobby':hobby}
# 序列化的过程
with open('userdb.pkl','ab') as f :
userbytes = pickle.dumps(user)
f. write(userbytes)
#反序列化的过程
with open('userdb.pkl','rb') as f :
userbytes = f.read()
user = pickle.loads(userbytes)
print(user)
# dump 直接序列化到文件
with open('userdb.pkl','ab') as f:
pickle.dump(user.f)
# load 从文件反序列化
with open('userdb.pkl','rb') as f:
user = pickle.load(f)
print(user)
print(pickle.load(f))
2. shelve 模块
shelve模块 也用于序列化,
它与pickle不同之处在于 : 不需要关心文件模式什么的. 直接把它当成一个字典来看待
它可以直接对数据进行修改 而不用覆盖原来的数据
而pickle 你想要修改只能 用wb模式来覆盖
示例:
import shelve
user = {'name':'高根'}
s = shelve.open('userdb.shv')
s['user'] = user
s.close()
s = shelve.open('userdb.shv',writeback = True)
print(s['user'])
s['user']['age'] = 20
s.close()
总结: 可以储存python所有基础数据类型,
只需要指定文件名字即可, 使用方法与字典类型相同
其实该模块是对pickle模块的封装, 使用起来更加简单
3. json 模块
pickle 和 shevle 序列化后的得到的数据 只有python才能解析,
通常企业开发不可能做一个单机程序, 都需要联网进行计算机的交互,
我们必须保证这个数据能够跨平台使用
JSON是什么? java script object notation 就是对象表示法.
var obj = {'name' : 'egon'}
对于我们开发而言 json就是一种通用的数据格式 任何语言都能解析
json中的数据类型 python中的数据类型 它俩的对应关系
{ } 字典 {}
[ ] 列表 []
string " " str ' '
int / float int / float 整型, 浮点型
true / false True / False 布尔值
null None 表示空
json 格式的语法规范 :
最外层通常是一个字典或列表 (字典用的最多)
{ } or [ ]
只要你想写一个json格式的数据. 那么最外层直接写 { }
字符串必须是双引号
你可以在里面套任意多的层次
json 模块的核心功能
dump dumps load loads 不带s的就是封装 write 和 read 的
示例:
# 反序列化
1. loads 模式
import json
with open('a.json','rt',encoding='utf-8') as f :
res = json.loads(f.read())
print(res)
2. load 模式
import json
with open('a.json','rt',encoding='utf-8') as f :
print(json.load(f))
# 序列化
1. dumps 模式
with open('b.json','wt',encoding='utf-8') as f:
f.write(json.dumps('传入的字符串'))
2. dump 模式
with open('b.json','wt',encoding='utf-8') as f :
json.dump('传入的字符串' , f)
# 小练习 : 从网上找一段数据 自己解析一下,
把数据复制到一个 json文件里面.
示例:
with open ('new.json','rt',encoding='utf-8') as f:
res = json.load(f)
print(res) # 想要改变格式的话,就用下面这种
for dic in res['第一层的名字']['想要打印出来的名字'] :
for key in dic:
print('%s:%s' %(key, dic[key]))
4. XML 模块
什么是xml:
是一种标记语言 (计算机能识别的文本)
xml 有什么用?
制定了一种文本书写规范,使得计算机能够轻松识别这些数据 就和python一样
为什么不直接用python语言来进行传输?
计算机识别起来太费劲(语法太多.变化太复杂) 所以需要一种更加简单的解决方案
学习的重点还是语法格式
1. 任何的起始标签都必须有一个结束标签.
< > </>
2.可以采用另一种简化语法, 可以在一个标签中同时表示起始和结束标签,
这种语法是在大于号之前紧跟着一个斜线</>, xml解析器会将其翻译成 <xxx><xxx/>.
例如 :<百度百科词条/>
3.标签必须按合适的顺序进行 行行嵌套. 所以结束标签必须按镜像顺序匹配
起始标签, 这好比是将起始和结束标签看作是数学中的左右括号 :在没有关闭所有的
内部括号之前, 是不能关闭外面的括号的.
4.所有的特性都必须有值
5.所有的特性都必须在值的周围加上双引号.
一个标签的组成部分 :
<tagename 属性名="属性值">文本内容
</tagename>
单标签的写法:
<tagename 属性名 = "属性值"/>
镜像关闭的顺序示例:
<a>
<b>
<c>
</c>
</b>
</a>
把你左右的同学的信息写成xml
<studentinfo>
<张三>
<age>22</age>
<gender>man</gender>
</张三>
<李四>
<age>23</age>
<gender>man</gender>
</李四>
</studentinfo>
总结 : xml也是一种中间格式. 也属于序列化方式之一
与json相比较 : 同样的数据, json 会比 xml 更小,效率更高
xml 需要根据文档结构 手动解析 而json 直接转对象
示例:
import xml.etree.ElementTree as ElementTree
# 解析xml 文件
tree = ElementTree.parse('d.xml')
print(tree)
#获取根标签
rootTree = tree.getroot()
三种获取标签的方式:
获取所有人的年龄 iter是用于在全文范围获取标签
for item in rootTree.iter ("age") :
# 一个标签的三个组成部分分别是:
print(item.tag) #标签名称
print(item.attrib) #标签的属性
print(item.text) #文本内容
第二种 从当前标签的字标签中找到一个名称为age的标签 如果有多个, 找到的是第一个
print(rootTree.find("age").attrib)
第三种 从当前标签的子标签中找到所有名称为age的标签
print(rootTree.findall("age"))
获取单个属性 :
stu = rootTree.find("stu")
print(stu.get("age"))
删除子标签
rootTree.remove(stu)
添加子标签 (首先要创建一个子标签)
newTag = ElementTree.Element("这是一个新标签",{"一个属性" : "属性值"})
rootTree.append(newTag)
写入文件内
tree.write('f.xml' , encoding='utf-8')
xml 的练习 (取出文件里的stu下的值.和girlfriend的值)
import xml.etree.ElementTree as ElementTree
tree = ElementTree.parse("f.xml")
rootTree = tree.getroot()
users = [ ]
for item in rootTree.iter('stu') :
user = item.attrib
print(user)
gitem = item.find('girlfrieng')
user['girlfriend'] = gitem.attrib
users.append(user)
print(users)
5. config parser 模块
用于解析配置文件的模块
何为配置文件 ?
包含配置程序信息的文件就成为配置文件
什么样的数据应作为配置信息
需要改, 但是不经常改的信息. 例如数据文件的路径. DB_PATH
配置文件中, 只有两种内容
一种是 section 分区
一种是 option 选项 (就是一个key = value形式)
我们用的最多的就是get功能 用来从配置文件获取一个配置选项
示例:
import configparser
# 创建一个解析器
config = configparser.ConfigParser()
# 读取并解析 test.cfg
config.read('test.cfg',encoding='utf-8')
#获取需要的信息
#获取所有分区
print(config.sections('user'))
#获取所有选项
print(config.options('user'))
#获取某个选项的值
print(config.get('path','DB_PATH'))
# get返回的都是字符串类型 如果需要转换类型 直接使用 get+对应的类型(bool int float)
print(config.getint('user','age')) #返回的是整数类型
# 是否存在某个选项
config.has_option('想要找的选项')
# 是否存在某个分区
config.has_section('想要找的分区')
不太常用的功能:
# 添加
config.add_section('想要添加的分区')
config.set('server','url','192.168.1.2') (添加选项和选项的值, 跟修改是一样的代码)
# 删除
config.remove_option('user','age') #把user分区下的 age选项给删除了
# 修改
config.set('server','url','192.168.1.2') #把url选项的值给改了.
# 写回文件中
with open('test.cfg','wt',encoding='utf-8') as f:
config.write(f)
# 根据当前平台的默认编码来设定写入的格式. win默认为 GBK.