Python:更新序列化对象

Python:更新序列化对象,python,serialization,deserialization,pickle,Python,Serialization,Deserialization,Pickle,我正在尝试执行一项简单的任务: 1.反序列化以前序列化的对象 2.正在更新此对象 3.将其序列化以供以后使用 我试着用泡菜做这件事,但运气不好。 首先,我要这样做: empty_list = [] f = open('backup.p', 'wb') pickle.dump(empty_list, f) f.close() 后来: f = open('backup.p', 'rb+') l = pickle.load(f) l.append('string') pickle.dump(l,

我正在尝试执行一项简单的任务:
1.反序列化以前序列化的对象
2.正在更新此对象
3.将其序列化以供以后使用

我试着用泡菜做这件事,但运气不好。
首先,我要这样做:

empty_list = []
f = open('backup.p', 'wb')
pickle.dump(empty_list, f)
f.close()
后来:

f =  open('backup.p', 'rb+')
l = pickle.load(f)
l.append('string')
pickle.dump(l, f)
f.close()
但当我再次尝试加载假定已更新的列表时:

f = open('backup.p', 'rb')
updated_list = pickle.load(f)
print(updated_list)  # prints [] instead of ['string']
f.close()
为什么对
dump()
的第二次调用不使用新列表
['string']
覆盖
backup.p
的内容?我是否必须删除buckup.p以获得所需的行为

在此之后:

f =  open('backup.p', 'rb+')
l = pickle.load(f)
您已将文件对象
f
定位在文件中的某个点,该点位于
空\u列表
的pickle之后。这意味着当您将另一个对象转储到文件时:

pickle.dump(l, f)
新的pickle在第一次pickle之后写入。您需要通过在转储新pickle之前清除文件来避免这种情况:

f.seek(0)
f.truncate()
或者转储到新文件,然后用新文件替换原始文件。(您也可以在末尾查找、转储、然后截断以清除任何后续垃圾,而不是查找、截断、转储。)

在此之后:

f =  open('backup.p', 'rb+')
l = pickle.load(f)
您已将文件对象
f
定位在文件中的某个点,该点位于
空\u列表
的pickle之后。这意味着当您将另一个对象转储到文件时:

pickle.dump(l, f)
新的pickle在第一次pickle之后写入。您需要通过在转储新pickle之前清除文件来避免这种情况:

f.seek(0)
f.truncate()

或者转储到新文件,然后用新文件替换原始文件。(您也可以在最后查找、转储,然后截断,以清除任何后续垃圾,而不是查找、截断、转储。)

添加
f.truncate(0)
在您的签名位置(在我的示例中,就在第二次
转储之前)会在以后尝试
加载
时导致
keyrerror
异常:
回溯(最后一次调用):文件“/test.py”,第28行,在更新的_list=pickle.load(f)文件“/usr/lib64/python2.6/pickle.py”中,第1370行,在加载返回Unpickler(File.load()文件“/usr/lib64/python2.6/pickle.py”中,第858行,在加载分派[key](self)键错误:“\x00”
”@so.very.dear:看起来我有点误解了
truncate
;如果被截断的文件比文件中的当前位置短,它实际上不会移动文件位置,因此您需要
seek
truncate
。在您签名的位置添加
f.truncate(0)
(在我的示例中,就在第二次
dump
之前)在尝试
load
时导致
KeyError
异常:“
Traceback(最近一次调用):File.”/test.py,第28行,在更新的\u list=pickle.load(f)文件“/usr/lib64/python2.6/pickle.py”,第1370行,在load return Unpickler(File).load()中文件“/usr/lib64/python2.6/pickle.py”,第858行,在load dispatch[key](self)KeyError:“\x00”
”@so.very.dear:看起来我有点误解了
truncate
;如果被截断的文件比文件中的当前位置短,它实际上不会移动文件位置,因此您需要
seek
truncate