我创建了一些数据并像这样存储了几次:
with open('filename', 'a') as f:
pickle.dump(data, f)
每次文件大小增加,但是当我打开文件时
with open('filename', 'rb') as f:
x = pickle.load(f)
我只能看到上次的数据。 如何正确读取文件?
Pickle 一次序列化一个对象,并读回一个对象 - 腌制的数据按顺序记录在文件中。
如果您只是这样做
pickle.load
,您应该读取序列化到文件中的第一个对象(而不是您编写的最后一个对象)。
反序列化第一个对象后,文件指针位于开头 下一个对象的 - 如果您再次调用
pickle.load
,它将读取下一个对象 - 这样做直到文件末尾。
objects = []
with (open("myfile", "rb")) as openfile:
while True:
try:
objects.append(pickle.load(openfile))
except EOFError:
break
pandas 0.22+ 中有一个 read_pickle 函数
import pandas as pd
obj = pd.read_pickle(r'filepath')
以下是如何写入和读取 pickle 文件的示例。请注意,如果您继续将 pickle 数据附加到文件中,则需要继续从文件中读取,直到找到所需的内容,或者到达文件末尾时生成异常。这就是最后一个函数的作用。
import os
import pickle
PICKLE_FILE = 'pickle.dat'
def main():
# append data to the pickle file
add_to_pickle(PICKLE_FILE, 123)
add_to_pickle(PICKLE_FILE, 'Hello')
add_to_pickle(PICKLE_FILE, None)
add_to_pickle(PICKLE_FILE, b'World')
add_to_pickle(PICKLE_FILE, 456.789)
# load & show all stored objects
for item in read_from_pickle(PICKLE_FILE):
print(repr(item))
os.remove(PICKLE_FILE)
def add_to_pickle(path, item):
with open(path, 'ab') as file:
pickle.dump(item, file, pickle.HIGHEST_PROTOCOL)
def read_from_pickle(path):
with open(path, 'rb') as file:
try:
while True:
yield pickle.load(file)
except EOFError:
pass
if __name__ == '__main__':
main()
我开发了一个软件工具,可以直接在浏览器中打开(大多数)Pickle 文件(不会传输任何内容,因此 100% 私密):
现在托管在这里:https://fire-6dcaa-273213.web.app/
编辑:如果您想将其托管在某个地方,可以在此处使用:https://github.com/ch-hristov/Pickle-viewer
请随意在某个地方托管此内容。
您还可以使用
joblib
来读取 pickle 文件。如果您正在阅读腌制的 scikit-learn 模型(joblib 附带 scikit-learn),它特别有用。
import joblib
x = joblib.load("my_file.pkl")
joblib
和pandas
都使用标准库中的pickle.load
,所以实际上,两者几乎相同:
with open("my_file.pkl", "rb") as f:
x = pickle.load(f)
只是文件处理和一些向后兼容性考虑是在 pandas 和 joblib 的幕后处理的。
特别是,对于OP的特定情况,它们无法工作,并且必须使用相同的try- except块来读取所有对象,例如:
objects = []
with open("myfile", "rb") as openfile:
while True:
try:
objects.append(pd.read_pickle(openfile))
except EOFError:
break