Python系列 46 内置模块:json&pickle&shelve
2021/7/4 14:21:23
本文主要是介绍Python系列 46 内置模块:json&pickle&shelve,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
序列化
序列化是指将在内存中的数据变成为可存储或者可传输的数据。
Python中称序列化为pickling,而其他编程语言中则称之为serialization、marshalling、flattening等等,都是一个意思。
序列化最重要的目的是数据持久化保存,以及数据跨平台传输:
- 持久化保存:数据无法在内存中长期驻留,因此可以将其转变为某种格式并写入到磁盘之中
- 跨平台传输:不同的编程语言中对于数据的表示都是不同的,如Python中的set在很多语言中就不具备,故可以将数据进行序列化,变为一种大家都认识的格式
json
JSON格式最早来源于JavaScript语言,现在已经成为跨平台语言传输的通用格式。
它的操纵及其简单,以下是JSON与Python中数据类型的对应关系:
Python数据类型 | JSON格式表示 |
---|---|
dict | {} |
list | [] |
str | string |
int or float | int or float |
True or False | true or false |
None | Null |
JSON优点是操纵简单、跨语言传输十分方便,因为它采用字符串进行存储。
JSON缺点是仅支持Python基本数据类型,像函数、类这种都不被支持。
Python中进行JSON格式化,可以选择内置的json模块:
官方文档
常用方法一览:
方法 | 描述 |
---|---|
json.dumps() | 将Python中的基本数据类型序列化为JSON格式的字符串 |
json.loads() | 将JSON格式字符串反序列化为Python中的基本数据类型 |
json.dump() | 同json.dumps(),不过写入文件更方便 |
json.load() | 同json.loads(),不过读取文件更方便 |
序列化
使用json.dumps()可以将Python中的基本数据类型序列化为JSON格式的字符串:
>>> import json >>> userMessage = {"name" : "yunya", "age" : "18", "gender" : True, "hobby" : ["read", "playGame"]} >>> json.dumps(userMessage) '{"name": "yunya", "age": "18", "gender": true, "hobby": ["read", "playGame"]}'
如果想将序列化的结果进行持久化保存,可以使用json.dump()方法,它可以指定输出对象为文件句柄,如下示例:
>>> import json >>> userMessage = {"name" : "yunya", "age" : "18", "gender" : True, "hobby" : ["read", "playGame"]} >>> with open(file="test.json", mode="wt", encoding="utf8") as f: json.dump(userMessage,fp=f)
反序列化
使用json.loads()可以将JSON格式字符串反序列化为Python中的基本数据类型:
>>> userJsonStr = '{"name": "yunya", "age": "18", "gender": true, "hobby": ["read", "playGame"]}' >>> json.loads(userJsonStr) {'name': 'yunya', 'age': '18', 'gender': True, 'hobby': ['read', 'playGame']}
如果想从文件中读取JSON字符串并进行反序列化,可以使用json.load()方法,它可以指定读取对象为文件句柄,如下所示:
>>> import json >>> with open(file="test.json", mode="rt", encoding="utf8") as f: userMessage = json.load(fp=f) >>> userMessage {'name': 'yunya', 'age': '18', 'gender': True, 'hobby': ['read', 'playGame']}
序列化的过程
Python的基本数据类型转换为JSON字符串时,经历了什么?
总计可分为2步:
- 修改str的单引号为双引号
- 根据JSON与Python中数据类型的对应关系,将数据进行包装转换为JSON表现形式
示例、修改str的单引号为双引号:
>>> pyStr = 'string' >>> jsonStr = json.dumps(pyStr) >>> jsonStr '"string"
示例、根据JSON与Python中数据类型的对应关系,将数据进行包装转换为JSON表现形式:
>>> pyType = None >>> jsonType = json.dumps(pyType) >>> jsonType 'null'
中文显示
如果JSON序列化的字符串中带有中文,则将其转变为Unicode的16进制表现形式:
>>> pyStr = "云崖先生" >>> json.dumps(pyStr) '"\\u4e91\\u5d16\\u5148\\u751f"'
你可以指定序json.dumps()中的关键字参数ensure_ascii为False,此时不会对中文字符进行转换:
>>> json.dumps(pyStr, ensure_ascii=False) '"云崖先生"'
猴子补丁介绍
Monkey Patch是指用一个补丁偷偷的将一个原本的功能进行替换,使用者并不知道目前使用的功能是已经替换后的功能。
第三方模块ujson相比于json来说性能更加的高效,你可以将它作为猴子补丁偷偷的替换掉json,只需要在项目运行时的入口加入并运行一个替换函数:
import json import ujson def monkeyPatchJson(): json.__name__ = "ujson" json.dumps = ujson.dumps json.loads = ujson.loads monkeyPatchJson()
修改完毕后,重启项目,后面的代码甚至不需要任何修改,就能使用性能更高的ujson了。
采用猴子补丁之后,如果发现ujson不符合预期,那也可以快速撤掉补丁,删除掉函数的执行语句即可。
序列化非基本数据类型
datetime类型并非是Python基本的数据类型,所以JSON不支持对它的序列化。
import datetime import json now = datetime.datetime.now() strNow = json.dumps(now, ensure_ascii=False) print(strNow) # TypeError: Object of type 'datetime' is not JSON serializable
此时我们可以手动的扩展json.dumps()的功能,让其支持datetime的序列化。
具体思路是将非Python基本数据类型转换为基本数据类型后再使用json.dumps()对其进行序列化,实现步骤如下所示:
import datetime import json from json.encoder import JSONEncoder class JsonRealize(JSONEncoder): """ 该类是自定义序列化非Python基本数据类型的逻辑实现类 主要作用是继承并覆写父类JSONEncoder的default() """ def default(self, serializeObject): # 发现序列化对象是datetime类型的话,就将其转换为str类型 if isinstance(serializeObject, datetime.datetime): return str(serializeObject) # 如果是其他类型,则交由JSONEncoder的default()进行处理 return JSONEncoder.default(self, serializeObject) if __name__ == '__main__': now = datetime.datetime.now() strNow = json.dumps(now, cls=JsonRealize, ensure_ascii=False) print(strNow) # "2021-05-23 20:40:49.446823"
json模块使用注意事项
Python3.6以及Python2.7之前均不支持反序列化bytes类型。
也就是说json.loads()一个bytes类型会抛出异常。
pickle
pickle模块是Python自带的模块,它和json模块的方法全部一致,区别在于pickle序列化后的类型是bytes类型,而json序列化后的类型是字符串类型。
由于要考虑到多语言的兼容性问题,json模块并不支持Python除基本数据类型之外的类型。如:函数类型,类等等。
但是pickle由于只支持Python使用,所以有了更强的对Python序列化对象的支持。
pickle可以序列化函数,类等等,但是并不推荐这么做,因为保存的只有一个内存地址。
另外,由于pickle的局限性太强所以更推荐使用JSON进行序列化操作。
由于很少使用,以及与json模块的方法一致,这里不再进行演示了。
官方文档
shelve
shelves是Python自带的模块,它能够更加方便的将Python数据进行持久化保存。
官方文档
它将整个文件看做一个大的字典,将字典中的key看做Python中的标识符,将value看做存储的对象,因此操作起来十分方便。
只需要记住2个方法即可:
- shelve.open():打开一个文件,这个文件是可读可写的
- shelve.close():关闭文件
示例演示:
>>> import shelve >>> with shelve.open("test.txt") as f: f["name"] = "Yunya" f["age"] = 18 f["hobby"] = ["readBook", "playGame"] >>> with shelve.open("test.txt") as f: name = f.get("name") >>> name 'Yunya'
这篇关于Python系列 46 内置模块:json&pickle&shelve的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-24Vue CLI多环境配置学习:从入门到实践
- 2024-11-24Vue CLI多环境配置学习:新手入门教程
- 2024-11-24Vue CLI学习:初学者指南
- 2024-11-24Vue CLI学习:从入门到上手的简单教程
- 2024-11-24Vue3+Vite学习:从零开始的前端开发之旅
- 2024-11-24Vue3阿里系UI组件学习入门教程
- 2024-11-24Vue3的阿里系UI组件学习入门指南
- 2024-11-24Vue3公共组件学习:新手入门教程
- 2024-11-24Vue3公共组件学习入门指南
- 2024-11-24vue3核心功能响应式变量学习