常用模块-pickle\json\xml\shelve\

什么是序列化?

将内存中的数据结构转化为一种中间格式,并存储到硬盘上
我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化

为什么要序列化?

就是为了将数据持久储存
序列化之后,不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好使用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现跨平台数据交互.

反序列化?

将硬盘上储存的中间格式数据再还原为内存中的数据结构

  • pickle模块
import pickle
# 用户注册后得到的数据
name = '高跟'
password = '123'
height = 1.5
hobbies = ['eat','drink','piao','du',{1,2,3}]

# 按照我们之前的方法储存
with open('userdb.txt','wt',encoding = 'utf-8') as f:
	test = '|'.join([name,password,str(height)])
	f.write(text)

# pickle支持python中所有的数据类型
user = {"name":name,"password":password,"height":height,"hobby":hobby,"test":3}

# 序列化的过程pickle.dumps
with open('userdb.pkl','ab') as f:
	userbytes = pickle.dumps(user)
	f.write(userbytes)
# 序列化pickle.dump
with open('userdb.pkl','ab') as f:
	pickle.dump(user,f)
'''dump和dumps的区别,dump帮你封装了write的方法,更方便一些'''

# pickle.loads 从文件反序列化
with open('userdb.pkl','rb') as f:
	userbytes = f.read()
	user = pickle.loads(userbytes)
	print(user)
# pickle.loads 反序列化
with open('userdb.pkl','rb') as f:
	user = picklel.load(f)
	print(user)
'''load和loads的区别,也是load封装了read功能'''

# 看到load封装了read的功能,想为什么不把打开文件也给封装了呢,我们可以自己封装一下
def myload(filename):   #给一个参数,要打开的文件
	with open(filename,'rb') as f:
		return pickle.load(f)
# 以后直接自己写的
  • 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 = Trun) #writeback(写回)参数默认为False 改为Trun,可以对数据进行修改
print(s['user'])
s['user']['age'] = 20
s.close()

pickle 和 shevle 序列化其实我们基本不用,因为他们序列化得到的数据只有python才能解析
通常企业开发不可能做一个单机程序,都是需要联网进行计算机间的交互的
我们必须保证数据能够跨平台使用

  • json模块:重点 (jave script object notation)

对于开发而言,json就是一种通用的数据格式 任何语言都可以解析,所以它可以跨平台使用

js中的数据类型python数据类型
{}dict
[]list
string""str
int/floatint/float
true/falseTrue/False
nullNone

json格式的语法规范:

  1. 最外层通常是一个字典或者列表
  2. 其实列表也不常用,只要你想写一个json格式的数据,那么最外层直接写{}
  3. 字符串必须时双引号
  4. 可以再里面套任意多的层次
  5. 写json格式的语法,最好用json的格式化
# json模块的核心功能
# dump dumps load loads 和pickle的用法差不多

import json
# 序列化
dic = {'name':'alex','age':28,'sex':'male'}
print(type(dic))  #<class 'dict'>

j = json.dumps(dic)
print(type(j))    #<class 'str'>

# 反序列化
with open("a.json","rt",encoding = "utf-8") as f:
	res = json.loads(f.read())
	print(res)

with open("a.json","rt",encoding = "utf-8") as f:
	print(json.load(f))

直接解析字符串的json为python对象

import json
# 直接解析字符串的json为python对象
jsontext = """{
	"user":[{
		"name":"egon",
		"age":18
	},
	{
		"name":"alex",
		"age":58
	}]
}
"""
res = json.loads(jsontext)
print(res)

将python对象序列化为json格式写入文件

import json

mydic = {
	'user':[{
		'name':'egon',
		'age':18
	},
	{
		'name':'alex',
		'age':58
	}]
}
# json.dumps
with open('b.json','wt',encoding = 'ust-8') as f:
	f.write(json.dumps(mydic))
# json.dump
with open('b.json','wt',encoding = 'ust-8') as f:
	json.dump(mydic,f)
  • xml模块

XML 可扩展的标记语言
<></>
也是一种通用的数据格式,也是跨平台
相比json比较复杂,xml比较早,所以很多写的找的数据都是用的xml记录的,我们在写的时候建议使用json

学习的重点和语法格式:

  1. 任何的起始标签都必须有一个结束标签
    <></>
  2. 可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在⼤于符号之前紧跟一个斜线</>,例如:<百度百科词条></百度百科词条>可以写成<百度百科词条/>
  3. 标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签.
  4. 所有的特性都必须有值
  5. 所有特性都必须在值得周围加上双引号.
'''
一个标签的组成部分
<tagename 属性名称 = '属性值'>文本内容
</tagename>
单标签的写法
<tagename 属性名称 = '属性值'/>

把你左右同学的信息写成xml
<studentinfo>
    <张三>
        <age>20</age>
        <gender>man</gender>
    </张三>
    <李四>
        <age>20</age>
        <gender>man</gender>
    </李四>
</studentinfo>

    总结 xml也是一种中间格式 也属于序列化方式之一
    与json相比较
    同样的数据  json会比xml 更小 效率更高
    xml 需要根据文档结构 手动解析 而json 直接转对象

'''
import xml.etree.ElementTree as ElementTree
# 解析d.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"))
print(stu.get("name"))

# 删除子标签
rootTree.remove(stu)


# 添加子标签
# 要先创建一个子标签
newTag = ElementTree.Element("这是新标签",{"一个属性":"值"})
rootTree.append(newTag)

# 写入文件
tree.write("f.xml",encoding="utf-8")

  • configparser模块

用于解析配置文件的模块
配置文件:包含配置程序信息的文件就是配置文件
配置信息:需要改,但不经常改的信息 例如数据文件的路径

配置文件中 只有两种内容

  1. section分区
  2. option选项 就是一个key=value形式
    我们一般用的最多的是get功能,用来从配置文件中获取一个配置选项
'''做一个登录 首先查看配置文件 是否又包含 用户名和密码 如果由直接登录 如果没有就进行输入用户名密码登录
    登录成功后 询问是否要保存密码  如果是 写入配置文件'''

import configparser
# 创建一个解析器
config = configparser.ConfigParser()
# 读取并解析test.cfg
config.read("test.cfg",encoding="utf-8")
# 获取需要的信息
# 获取所有分区
print(config.sections())
# 获取所有选项
print(config.options("user"))
# 获取某个选项的值
print(config.get("path","DB_PATH"))
print(type(config.get("user","age")))

# # get返回的都是字符串类型  如果需要转换类型 直接使用get+对应的类型(bool int float)
print(type(config.getint("user","age")))
print(type(config.get("user","age")))

# 是否由某个选项
config.has_option()
# 是否由某个分区
config.has_section()

# 不太常用的
# 添加
config.add_section("server")
config.set("server","url","192.168.1.2")
# 删除
config.remove_option("user","age")
# 修改
config.set("server","url","192.168.1.2")

# 写回文件中
with open("test.cfg", "wt", encoding="utf-8") as f:
    config.write(f)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值