gpt4 book ai didi

python - 我如何使用散列和 pickle 来保存/加载对象

转载 作者:行者123 更新时间:2023-12-04 16:10:55 24 4
gpt4 key购买 nike

所以我正在按照一本关于使用随机文件的书中的指南进行操作,并使用以下代码来保存一些对象

import pickle
from carRec import carRec

cars = [carRec(1, "Ford", "Escort"), carRec(2, "Ford", "Focus"), carRec(3, "Ford", "Mustang")]

#output to carsFile
carFile = open("carsRand.dat", "wb")

for i in range(0,3):
address = hash(cars[i].vehicleID)
carFile.seek(address)
pickle.dump(cars[i], carFile)

carFile.close()

然后加载数据

import pickle
from carRec import carRec

carFile = open("cars.dat", "rb")
cars = []
counter = 1

try:
while True:
location = hash(counter)
carFile.seek(location)
cars.append(pickle.load(carFile))
counter += 1
except EOFError:
print("done")

carFile.close()

问题是,当我尝试重新加载数据时出现以下错误

_pickle.UnpicklingError: invalid load key, ''.

快速查看 dat 文件让我觉得数据写入工作不正常。我相信,当使用散列和查找函数来识别写入位置/读取位置时,您需要允许以字节为单位的记录大小。如果是这种情况,我如何 a) 确保所有记录的大小相同以及 b) 找出单个记录的大小?

最佳答案

此代码的问题在于,汽车对象在写入时会覆盖之前写入的汽车对象。这可以通过直接 pickle 列表来解决:

import pickle
with open("cars.dat", "wb") as f:
pickle.dump(cars, f)

然后可以加载:

with open("cars.dat", "rb") as f:
cars = pickle.load(f)

如果您绝对必须单独 pickle 对象,您可以使用 len(pickle.dumps(obj, -1)) 确定对象的 pickle 大小

此外,您是否考虑过使用 shelve 模块?这是将简单的 Python 对象保存到文件中的最简单方法。

编辑:确保记录大小相同的最简单方法是不使用 pickle。但是,您可以将记录的大小与记录一起存储:

import pickle
import struct

with open("cars.dat", "wb") as f:
for car in cars:
size = len(pickle.dumps(car, -1))
f.write(struct.pack("<I", size))
pickle.dump(car, f)

此代码在每条记录前存储 4 个字节的长度信息。然后可以使用 struct.unpack("<I", f.read(4))[0] 加载此长度数据

然后您还可以将每个(长度、数据)对的偏移量存储在文件的开头,以允许读取第 n 条记录而无需遍历所有先前的记录。

关于python - 我如何使用散列和 pickle 来保存/加载对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41766433/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com