#Python 的数据持久化
程序中的数据都保存在内存中,如果希望程序退出后,下次运行时仍能使用之前的数据,就需要对数据进行 持久化,也就是将数据保存到持久性存储器(通常是硬盘)中。
例如如下数据,是游戏中角色的名字、最大血量、当前血量:
player_state:dict = {
'name': 'link',
'max_hp': 10,
'current_hp': 7,
}
玩家退出游戏时,需要将该数据保存到硬盘上,我们无法轻易地将数据直接写入硬盘,通常需要将对象转换为 str
或 bytes
后再进行写入。
相应的,在下一次启动游戏时,我们需要读取数据后转换回原来的 dict
。
将数据转换为 str
或 bytes
的过程称作 序列化 或 编码,反之责备称作 反序列化 或 解码。
示例:
# 数据
player_state:dict = {
'name': 'link',
'max_hp': 10,
'current_hp': 7,
}
# 通过 str 函数转换为字符串后写入文件保存
with open("save.data", "w", encoding="utf-8") as fp:
fp.write(str(player_state)) # str 函数对复杂对象的转换不一定符合预期,请勿用作序列化
# ...
# 下次启动,读取文件
with open("save.data", "r", encoding="utf-8") as fp:
data = fp.read()
# 转换回 dict
backup_state = eval(data) # eval 可以执行任何代码,非常危险,请勿用于反序列化
# 查看数据
print(backup_state)
#Python 的对象序列化
Python 中,可以使用内置的 pickle
模块保存和加载对象,dump
函数将对象编码为 bytes
并存入文件,load
函数读取文件并解码为对象。
函数 | 说明 |
---|---|
dumps | 将对象编码为 bytes |
loads | 将 byes 解码为对象 |
dump | 将对象编码为 bytes 并写入文件 |
laod | 读取文件中的 bytes 并解码为对象 |
函数说明:
def dumps(obj) -> bytes:
'''
将对象编码为 bytes
:param obj: 要保存的对象
:return: 转换后的 bytes
'''
pass
def loads(data:bytes):
'''
将 bytes 解码成对象
:param data: 要解码的 bytes
:return: 解码出的对象
'''
pass
def dump(obj, fp):
'''
将对象编码为 bytes 保存到文件中
:param obj: 要保存的对象
:param fp: 要写入的文件流
'''
pass
def load(fp):
'''
读取文件中的 bytes 解码成对象
:param fp: 要读取的文件流
:return: 解码出的对象
'''
pass
示例:
import pickle
# 数据
player_state:dict = {
'name': 'link',
'max_hp': 10,
'current_hp': 7,
}
# 通过 pickle.dump 转换为 bytes 后写入文件保存
with open("save.data", "wb") as fp:
pickle.dump(player_state, fp)
# ...
# 下次启动,通过 pickle.load 加载数据
with open("save.data", "rb") as fp:
backup_state = pickle.load(fp)
# 查看数据
print(backup_state)
pickle
只能用于 Python,并且在 Python 的不同版本之间也存在不兼容的可能性。