在Python中,序列化是将对象转换为可存储或传输的格式(如字节流或字符串),而反序列化则是将序列化后的数据重新转换为对象(官网序列化)。
序列化:就是将不能存储的对象转为可存储的对象(封存pickling)。
发序列化:序列化的对象返回成原来的对象(解封unpickling)。
序列化和反序列化有下面五种方式
pickle
模块 官网概念:pickle
模块实现了对一个Python对象结构的二进制序列化和反序化。"pickling" 是将 Python 对象及其所拥有的层次结构转化为一个字节流的过程而 "unpickling" 是相反的操作,会将(来自一个二进制文件或字节对象的)字节流转化回一个对象层次结构。 pickling(和 unpickling)也被称为“序列化”, “编组”或者 “平面化”。而为了避免混乱,此处采用术语 “封存 (pickling)” 和 “解封 (unpickling)”
核心函数
dumps:将Python对象序列化并写入到文件,常用写法pickle.dumps(对象)
loads: 将字节流反序列化为Python对象,常用写法pickle.
loads(对象)
# 大家还记得几种 import的用法
from pickle import dump,dumps,load,loads
retData = [
123,
[123,{'name':'python','age':18},'test pick'],
{'name':'java','age':18},
'test dump dumps load loads'
]
# 查询方法和属性print(help(dumps)) dumps(obj, protocol=None, *, fix_imports=True, buffer_callback=None)
'''
有些人想知道这个参数protocol是什么意思查询这个https://docs.python.org/zh-cn/3.13/library/pickle.html#pickle.Pickler
可选参数protocol 是一个整数,告知 pickler 使用指定的协议,可选择的协议范围从 0 到 HIGHEST_PROTOCOL。如果没有指定,这一参数默认值为 DEFAULT_PROTOCOL。指定一个负数就相当于指定 HIGHEST_PROTOCOL。
其他参数也有我就不细说了 想查询通过python官网查询选择对应的版本哦
'''
# 序列化
dumps_object = dumps(retData)
print(dumps_object)
# 反序列化
loads_object = loads(dumps_object)
print(loads_object)
dump:将Python对象序列化为字节流并写入文件,常用写法pickle.dump(对象,'输出地址')
load:从文件中读取出来字节流转为python对象,常用写法pickle.load(对象,'输出地址')
# 查询方法和属性print(help(dump)) dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None)
'''
回忆第八天学习的内容了
with open rb是不是读取二进制文件
with open wb写入二进制文件
'''
# 创建到跟当前python文件同目录 如果 python不存在python会自动创建
file_path = 'python.txt'
with open(file_path, 'wb') as file:
dump(retData,file)
# 查询方法和属性print(help(load)) load(file, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=())
with open(file_path,"rb") as file:
loaded_data = load(file)
print(loaded_data)
对比
函数名 | 功能描述 | 参数说明 | 返回值或行为 |
---|---|---|---|
pickle.dumps(obj) |
将 Python 对象序列化为字节流。 | obj :要序列化的 Python 对象。 |
返回序列化后的字节流(bytes 类型)。 |
pickle.loads(data) |
将字节流反序列化为 Python 对象。 | data :序列化后的字节流(bytes 类型)。 |
返回反序列化后的 Python 对象。 |
pickle.dump(obj, file) |
将 Python 对象序列化并写入文件。 | obj :要序列化的 Python 对象。file :文件对象(以二进制写模式打开)。 |
无返回值。将序列化后的字节流写入文件。 |
pickle.load(file) |
从文件中读取字节流并反序列化为 Python 对象。 | file :文件对象(以二进制读模式打开)。 |
返回反序列化后的 Python 对象。 |
json
模块官网概念:JSON(JavaScriptObjectNotation),由RFC7159(它取代了RFC4627)和ECMA-404进行规范,是一个受到JavaScript对象字面值语法启发的轻量级数据交换格式(虽然它并不是严格意义上的JavaScript子集)。
核心函数:不写了,还是dumps、dump、loads、load(可以自己写写感受不同的场景使用,具体场景看下面对比)
from json import dumps,dump,loads,load
data = {
'name': 'python',
'age': 18,
'capacity': ['json', 'pickle','marshal','yaml']
}
# 序列化到文件
with open('data.json', 'w') as f:
dump(data, f)
# 序列化为字符串
json_string = dumps(data)
print(json_string)
# 从文件反序列化
with open('data.json', 'r') as f:
loaded_data = load(f)
print(loaded_data)
# 从字符串反序列化
deserialized_data = loads(json_string)
print(deserialized_data)
官网概念:此模块包含一些能以二进制格式来读写Python值的函数。这种格式是Python专属的,但是独立于特定的机器架构(即你可以在一台PC上写入某个Python值,将文件传到一台Mac上并在那里读取它)。这种格式的细节有意不带文档说明;可可能在不同Python版本之间发生改变(但这种情况极少发生)。
核心函数:dumps、dump、loads、load(可以自己写写感受不同的场景使用,具体场景看下面对比)
from marshal import dump,dumps,load,loads
data = {
'name': 'python',
'age': 18,
'capacity': ['json', 'pickle','marshal','yaml']
}
# 序列化到文件
with open('data.marshal', 'wb') as f:
dump(data, f)
# 序列化为字节流
serialized_data = dumps(data)
# 从文件反序列化
with open('data.marshal', 'rb') as f:
loaded_data = load(f)
print(loaded_data)
# 从字节流反序列化
deserialized_data = loads(serialized_data)
print(deserialized_data)
yaml
是一种人类可读的数据序列化格式,适合配置文件和数据交换(第三方类库)。
pip install pyyaml
只有load、dump方法
from yaml import dump,load
data = {
'name': 'python',
'age': 18,
'capacity': ['yaml', 'pickle','marshal','json']
}
# 序列化到文件
with open('data.yaml', 'w') as f:
dump(data, f)
# 序列化为字符串
yaml_string = dump(data)
print(yaml_string)
# 从文件反序列化
with open('data.yaml', 'r') as f:
loaded_data = load(f, Loader=yaml.FullLoader)
print(loaded_data)
# 从字符串反序列化
deserialized_data = load(yaml_string, Loader=yaml.FullLoader)
print(deserialized_data)
官网概念:"Shelf"是一种持久化的类似字典的对象。与"dbm"数据库的区别在于Shelf中的值(不是键!)实际上可以为任意Python对象---即pickle模块能够处理的任何东西。这包括大部分类实例、递归数据类型,以及包含大量共享子对象的对象。键则为普通的字符串。
核心函数
open:打开一个持久化字典。filename指定下层数据库的基准文件名。作为附带效果,会为filename添加一个扩展名并且可能创建更多的文件。默认情况下,下层数据库会以读写模式打开。可选的flag形参具有与dbm.open()flag形参相同的含义。
import shelve
data = {
'name': 'python',
'age': 18,
'capacity': ['json', 'pickle','marshal','yaml']
}
# 序列化到文件 open(filename, flag='c', protocol=None, writeback=False)
with shelve.open('data.db') as db:
db['key'] = data
# 从文件反序列化
with shelve.open('data.db') as db:
loaded_data = db['key']
print(loaded_data)
其实这几个模块的函数写法几乎一致,只不过对应的场景不同,写一个其他的知道使用场景即可。
方法 | 格式 | 可读性 | 支持对象类型 | 适用场景 |
---|---|---|---|---|
pickle |
二进制 | 不可读 | 几乎所有 Python 对象 | Python 内部数据存储 |
json |
文本 | 可读 | 基本数据类型 | 跨语言数据交换 |
marshal |
二进制 | 不可读 | 基本数据类型 | Python 内部使用 |
yaml |
文本 | 可读 | 复杂数据类型 | 配置文件、数据交换 |
shelve |
二进制 | 不可读 | 几乎所有 Python 对象 | 简单持久化存储 |