【问题标题】:Python: Update serialized objectPython:更新序列化对象
【发布时间】:2016-09-02 19:44:17
【问题描述】:

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

我试图用pickle 来做这件事,但没有运气。
我首先这样做:

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 才能获得所需的行为?

【问题讨论】:

    标签: python serialization deserialization pickle


    【解决方案1】:

    之后:

    f =  open('backup.p', 'rb+')
    l = pickle.load(f)
    

    您已将文件对象f 定位在文件中empty_list 的pickle 之后的某个点。这意味着当您将另一个对象转储到文件时:

    pickle.dump(l, f)
    

    新的pickle 写在第一个pickle 之后。您需要通过在转储新泡菜之前清除文件来避免这种情况:

    f.seek(0)
    f.truncate()
    

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

    【讨论】:

    • 添加 f.truncate(0) 在您输入的位置(在我的示例中,在第二个 dump 之前)在稍后尝试 load 时会导致 KeyError 异常:“Traceback (most recent call last): File "./test.py", line 28, in <module> updated_list = pickle.load(f) File "/usr/lib64/python2.6/pickle.py", line 1370, in load return Unpickler(file).load() File "/usr/lib64/python2.6/pickle.py", line 858, in load dispatch[key](self) KeyError: '\x00'
    • @so.very.tired:看来我有点误解truncate了;如果截断的文件比您在文件中的当前位置短,它实际上不会移动文件位置,因此您需要seektruncate
    猜你喜欢
    • 2021-08-18
    • 1970-01-01
    • 2012-11-14
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 2012-09-02
    相关资源
    最近更新 更多