python之序列化与反序列化(json与pickle)

python之序列化与反序列化(json与pickle)

一、什么是序列化与反序列化

1.序列化
  • 把某个语言的变量转成 json 格式字符串
  • 内存中的数据结构**----->转成一种中间格式(字符串)----->**存到文件中
2.反序列化
  • json 格式字符串转成某个语言的变量
  • 文件**----->读取中间格式(字符串)----->**eval( ) 转成内存中数据结构
3.json标准格式字符串
  • {“name” : “zb”, “age” : 18, “local” : true, “xx” : null}
  • json格式字符串符号必须是双引号

二、为什么要序列化

序列化的两种用途

1.持久保持状态
  • 一个软件或程序的运行就是在处理一系列状态的变化, 编程语言中, "状态"会以各种各样有结构的数据类型(或变量)保存在内存中
  • 而内存是无法永久保存数据的, 当断电或者是重启程序, 内存中那些有结构的数据都会被清空
  • 那么序列化就是在你机器在断电或重启之前将当前内存中的数据都保存到文件中去,下次执行程序可以直接载入之前的数据, 然后继续执行 (就相当于单机游戏存档)
# 存取数据 (格式标准), 一个程序写入, 另一个程序读取 (这两个程序可以是使用不同的语言写的)  
2.跨平台数据交互
  • 序列化之后,不仅可以将序列化后的内容存入磁盘, 也可以通过网络传输到别的机器上
  • 如果发送和接收方都约定好使用同一种序列化的格式, 那么便屏蔽了平台和语言所带来的的差异性, 实现了跨平台数据交互
  • 反过来, 把数据(变量)内容从序列化的对象重新读到内存中, 这就称之为反序列化
# 后端给前端的数据就是 "json" 格式字符串

三、json能序列化的类型

  • json 模块可以序列化:字典,列表,布尔
  • json 数据类型和 python 数据类型对应关系表如图所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mtk4lbdx-1625827116670)(C:\Users\pilgirm\AppData\Roaming\Typora\typora-user-images\image-20210709181410520.png)]

  • json格式序列化后与原数据类型的区别:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DSsuInfP-1625827116672)(C:\Users\pilgirm\AppData\Roaming\Typora\typora-user-images\image-20210709181456365.png)]

四、json序列化与反序列化的使用

1.json序列化与反序列化基本使用
import json

# 1. 序列化: 注意!序列化以后。返回的类型是字符串类型。
res = json.dumps([1, 1.1, True, False, None, {'name': 'jack'}])
print(res, type(res))  # [1, 1.1, true, false, null, {"name": "jack"}] <class 'str'>

# 2. 反序列化: 序列化以后。拿回到了原来的类型。
res = json.loads(res)
print(res, type(res))  # [1, 1.1, True, False, None, {'name': 'jack'}] <class 'list'>
2.json序列化的结果写入文件与读取json字符串格式进行反序列化操作
序列化的结果写入文件
  • dump()和dumps()
import json

# 一. 序列化的结果写入文件
# 1. 方法一: json.dumps
info = [1, 1.1, True, False, None, {'name': 'jack'}]
res = json.dumps(info) # 提示: 序列化以后返回的是字符串类型,所以可以写入写入文件。
with open('a.json', 'wt', encoding='utf-8') as f:
    f.write(res)

# 2. 方法二: json.dump, 写入文件推荐使用这种方式
info = [1, 1.1, True, False, None, {'name': 'jack'}]
with open('a.json', 'wt', encoding='utf-8') as f:
    json.dump(info, f) #自带f.write(),无需调用f.write()功能,将传进去的info序列化为json格式后写入到文件对象f中
从文件读取json格式的字符串进行反序列化操作
  • load()和loads()
# 1. 方式一: json.loads
with open('a.json', 'rt', encoding='utf-8') as f:
    res = json.loads(f.read())
    print(res, type(res))  # [1, 1.1, True, False, None, {'name': 'jack'}] <class 'list'>

# 2. 方式二: json.load, 文件读json格式的字符串,推荐使用这种方式。
with open('a.json', 'rt', encoding='utf-8') as f:
    print(json.load(f)) #自带f.read()

五、序列化总结

  • json 模块可以序列化:字典,列表,布尔
  • json.dumps()是一般序列化,json.loads()是一般反序列化
  • loadloads 都是实现反序列化,dumpsdump都是实现序列化
  • loaddump都是针对的文件对象,使用这两种默认自带读写功能,不需要调用.read().write()功能
  • load读取文件内容将其反序列化,返回反序列化后的内容
  • dump将传进去的值序列化为json格式的后写入保存到文件对象中

json

使用json的4点注意须知

img

import json

# 须知一: json兼容的是所有语言通用的数据类型。不能识别某一语言的独有类型。而Python中的独有类型就含有集合, 所以json不能识别。
json.dumps({1, 2, 3})  # TypeError: Object of type set is not JSON serializable

# 须知二: json格式中的字符串必须使用双引号。json 不认单引号. 
json.loads("['logging_test', 'config_test']")  # json.decoder.JSONDecodeError: Expecting value: line 1 column 2 (char 1)

# 须知三. 无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads(上面如图所示。展示json格式是怎么样表达的)

# 须知四. json针对中文时的序列化与反序列化(针对中文的序列化会把它转成一种特定的json编码格式, 并不能与英文字符串一样能直观的看到。)
res = json.dumps('我是中文')
print(res, type(res))  # "\u6211\u662f\u4e2d\u6587" <class 'str'>

res = json.loads(res)
print(res, type(res))  # 我是中文 <class 'str'>

六、使用json序列化byte类型

  • 演示
import json

dic = {"name": "裂开", "age": 22}
res = json.dumps(dic)
print(res)  # {"name": "\u6d3e\u5927\u661f", "age": 22}
  • 加入 ensure_ascii=False 功能
dic = {"name": "裂开", "age": 22}
res = json.dumps(dic,ensure_ascii=False)
print(res)  # {"name": "裂开", "age": 22}
  • 问题总结
# 并没有使用上的变化, 存的是什么, 取出来的还是什么, 只不过人家内部帮你转成"uncode"格式保存

ps : java中,出于性能的考虑,有很多包来完成序列化和反序列化:谷歌的gson 阿里开源fastjson 等等

补充:
# 了解: python2当中str就是bytes类型. 在python解释器2.7与3.6之后都可以json.loads(bytes类型), python3中字符串其实等同于Unicode编码格式。但是在除了python3.5, json内部对这种的表达形式做了优化, 让在python3中也可以使用,但唯独3.5不可以
>>> import json
>>> json.loads(b'{"a":111}')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/linhaifeng/anaconda3/lib/python3.5/json/__init__.py", line 312, in loads
    s.__class__.__name__))
TypeError: the JSON object must be str, not 'bytes'  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值