首页 > 解决方案 > python搁置:重新打开搁置后相同的对象变成不同的对象

问题描述

我使用搁置看到这种行为:

import shelve

my_shelve = shelve.open('/tmp/shelve', writeback=True)
my_shelve['a'] = {'foo': 'bar'}
my_shelve['b'] = my_shelve['a']
id(my_shelve['a'])  # 140421814419392
id(my_shelve['b'])  # 140421814419392
my_shelve['a']['foo'] = 'Hello'
my_shelve['a']['foo']  # 'Hello'
my_shelve['b']['foo']  # 'Hello'
my_shelve.close()

my_shelve = shelve.open('/tmp/shelve', writeback=True)
id(my_shelve['a'])  # 140421774309128
id(my_shelve['b'])  # 140421774307832 -> This is weird.
my_shelve['a']['foo']  # 'Hello'
my_shelve['b']['foo']  # 'Hello'
my_shelve['a']['foo'] = 'foo'
my_shelve['a']['foo']  # 'foo'
my_shelve['b']['foo']  # 'Hello'
my_shelve.close()

正如您所看到的,当搁置重新打开时,以前是同一个对象的两个对象现在是两个不同的对象。

  1. 有人知道这里发生了什么吗?
  2. 有人知道如何避免这种行为吗?

我正在使用 Python 3.7.0

标签: pythonpicklepython-internalspython-3.7shelve

解决方案


shelve将对象的腌制表示存储到架子文件中。my_shelf['a']当您存储与和相同的对象时my_shelf['b']shelve为键写入对象的pickle,'a'并为键写入对象的另一个pickle 'b'。需要注意的一件事是它分别腌制所有值。

当您重新打开架子时,shelve使用腌制表示来重建对象。它使用 pickle for'a'重建您存储的 dict ,并使用 pickle for重建'b'您存储的 dict 。

泡菜不相互交互,也没有任何方法可以在取消腌制时返回相同的对象。磁盘上的表示中没有任何迹象表明my_shelf['a']my_shelf['b']曾经是同一个对象;使用单独的对象制作的架子,my_shelf['a']并且my_shelf['b']看起来可能相同。


如果您想保留这些对象相同的事实,则不应将它们存储在架子的单独键中。考虑使用'a'and'b'键而不是使用shelve.


推荐阅读