python中常用的序列化模块_第六章 常用模块(5):python常用模块(序列化模块:pickle,json,shelve,xml)...

6.3.7 序列化模块 (pickle,json,shelve,xml)

文件写入,数据传输时,我们都是以字符串形式写入的(因为字符串可以encode成bytes)。

那其他类型(比如字典,列表等)想写入文件时如何处理呢?

这时候我们就需要一种操作,叫做序列化。

+那什么是序列化呢?

+ 把内存数据(unicode)转成字符(bytes类型),叫做序列化。

>序列化用于存入硬盘或者网络传输等

+ 把字符转成内存数据,叫反序列化。

简单点说,就是:

序列化: 其他类型数据 --> 字符类型

反序列化: 字符类型 --> 其他数据类型

>字符类型:str, bytes or bytearray

可以序列化,反序列化的模块有以下2种:

pickle

json

这两种模块的用法完全一样

用eval()方法也可以达到效果。那有什么区别呢?

1. json模块 (.json文件)

序列化成字符串类型

json特点

需要用open打开文件再处理

用'w','r'等类型打开文件进行

序列化成字符串类型

文件扩展名用.json

json与pickle的区别:

json能识别的数据类型:str,int,tuple,list,dict

json可以跨平台使用

import json

json.dump(obj,fp,skipkeys,...)

将obj序列化成字符串类型,并写入文件对象fp中。返回None

json.dumps():将数据转成字符串并存到内存

这个一般用在:1.网络数据传输 2.跨平台,跨语言的数据交互

json.load(fp,cls,...)

读取json序列化的文件对象fp,反序列,返回反序列后的数据

json.loads():读取dumps的数据,并反序列

import json

data = {'name': 'Alex', 'age': 22, 'salary': [1, 2, 3]}

# d1 = json.dumps(data) # 把data序列化。 ->序列化后转为str类型

# d2 = json.loads(data) # 把data反序列化。 ->反序列化转成相应数据类型(字典,列表等)

with open('test.json','w') as f: # 一般json序列化的文件扩展名用.json

d1 = json.dump(data,f) # 把data序列化,并且写入文件对象f中。因为返回None,所以d1是None

with open('test.json','r') as f:

d2 = json.load(f) # 把文件对象f的数据反序列化,返回给d2

拓展:数据交互方式有2种:json,xml

json 可读性,数据大小 都优越于 xml

Azure的旧环境用的xml,新环境用的json

2. pickle模块 (.pkl文件)

序列化成bytes类型。

注意:因为序列化成bytes类型,所以文件的读写要用rb,wb等模式来进行!

pickle特点

需要用open打开文件再处理

用'wb','rb'等类型打开文件进行

序列化成bytes类型

文件扩展名用.pkl

pickle与json的区别:

pickle支持python里所有的数据类型(比如函数,类什么的都可以)

所以python使用的文件,不论内容时什么我们都可以pickle

pickle只能在python里使用

import pickle

pickle.dump(obj,file,protocol,...)

将obj序列化成bytes类型,并写入file文件,如果没有会创建文件。返回None

pickle.load(file,...)

读取json序列化的文件对象fp,反序列,返回反序列后的数据

.loads():读取dumps的数据,并反序列

import pickle

data = [1, 2, 3]

d1 = pickle.dumps(data) # 把data序列化。 ->序列化后转为bytes类型

d2 = pickle.loads(d1) # 把data反序列化。 ->反序列化转成相应数据类型

with open('test.pkl', 'wb') as f: # 一般pickle序列化的文件扩展名用.pkl

pickle.dump(data, f)

with open('test.json', 'rb') as f:

d = pickle.load(f)

print(type(d1))

print(type(d2))

print(d)

3. shelve模块 ()

shelve对pickle进行了封装,并且可以多次dump和load

区别及特点:

pickle

一个文件只能dump一次(因为dump多次容易混乱)

用open()函数打开文件

shelve

可以对文件多次dump,load

用shelve模块的.open()方法打开文件

数据的结构类似dict

可以直接用类似处理dict的方法处理数据

序列化:

import shelve

f = shelve.open('shelve_test') # 打开(没有就创建)文件。会创建多个文件。可以跟open一样用with

list1 = ['a','b','c','d']

dict1 = {'key1':'abcd','key2':'1234'}

f['li1'] = list1 # 持久化列表 --> 就是写入序列化文件中,并且有个名字是'li1'

f['d1'] = dict1 # 持久化字典 --> 就是写入序列化文件中,并且有个名字是'd1'

f.close() # 关闭保存

反序列化:

import shelve

with shelve.open('shelve_test') as f:

print(f['li1']) # 直接调用li1的数据

print(f['d1']) # 直接调用d1的数据

# shelve打开的文件对象构造类似字典,可以使用字典的方法:

print('get li1:', f.get('li1')) # 有get()方法

i = f.items() # 有items()方法。 注意:这个i指向f.items()的内存地址,f.items()的值变化,i也会随之变化

print(id(i))

print(i) # 返回值是shelve对象类型,不能直接使用

print(list(i)) # 所以需要list()转换一下才可以看到内容

f['li2'] = ['aaaa','bbbb'] # 可以追加新的数据

print(list(i))

f.pop('li2') # 可以删除

print(list(i))

f['li1'] = [2, 3, 4, 5] # 可以直接修改某个数据的整个内容

print(list(i))

f['li1'][1] = 'b' # 但是不能改其中的一部分内容(字典可以)

print(list(i)) # 结果并没有改变

print(id(i))

4. xml模块 (.xml)

作用和json一样,是json出现之前很常用的序列化模块。

构造也和字典类似。用<>来定义数据。

读取xml文档内容:

# 读取数据

import xml.etree.ElementTree as ET

tree = ET.parse('test.xml') # 打开xml文件,返回xml对象

root = tree.getroot() # 取数据最上级key

# print(dir(root)) # 可以显示数据的keys

print(root.tag)

# 遍历文档

for child in root:

print(child.tag, child.attrib)

for i in child:

print(i.tag, i.attrib)

# 只遍历year节点

for node in root.iter('year'):

print(node.tag, node.text)

修改和删除xml文档内容:

# 修改数据

import xml.etree.ElementTree as ET

tree = ET.parse('test.xml')

root = tree.getroot() # 取数据最上级key

# 修改

for node in root.iter('year'):

new_year = int(node.text) + 1 # 取数据并计算

node.text = str(new_year) # 把值转成str并赋值给原来的内容

node.set('update', 'yes') # 设置属性和值

tree.write('test.xml') # 内容写入文件

# 删除数据

import xml.etree.ElementTree as ET

tree = ET.parse('test.xml')

root = tree.getroot() # 取数据最上级key

# 删除node

for country in root.findall('country'):

rank = int(country.find('rank').text)

if rank > 50:

root.remove(country)

tree.write('output.xml') # 结果写到一个新文件里

创建xml文件

```python

# 创建xml文件

import xml.etree.ElementTree as ET

root = ET.Element('namelist') # 创建名为namelist的根(root)

name1 = ET.SubElement(root,'name',attrib={'enrolled':'yes'}) # 名称为'name'的数据放在'root'的节点上,属性设为{'enrolled':'yes'}

age = ET.SubElement(name1,'age',attrib={'checked':'no'}) # 名称为'age'的数据放在name1的节点上,属性设置为 {'checked':'no'}

sex = ET.SubElement(name1,'sex') # 名称为'sex'的数据放在name1的节点上

sex.text = '33' # sex的值设为'33'

name2 = ET.SubElement(root,'name',attrib={'enrolled':'no'}) # 名称为'name'的数据放在'root'的节点上,属性设为{'enrolled':'yes'}

age = ET.SubElement(name2,'age') # 名称为'age'的数据放在name2的节点上

age.text = '19' # age的值设为'19'

et = ET.ElementTree(root) # 生成文档对象

et.write('test.xml', encoding='utf-8', xml_declaration=True) # xml_declaration是要不要加版本号声明

ET.dump(root)

```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值