尝试在书架中存放双端队列的奇怪行为

时间:2012-06-21 20:08:53

标签: python shelve

我将让以下终端会议说明一切:

>>> import shelve
>>> s = shelve.open('TestShelve')
>>> from collections import deque
>>> s['store'] = deque()
>>> d = s['store']
>>> print s['store']
deque([])
>>> print d
deque([])
>>> s['store'].appendleft('Teststr')
>>> d.appendleft('Teststr')
>>> print s['store']
deque([])
>>> print d
deque(['Teststr'])

ds['store']不应指向同一个对象吗?为什么appendleft适用于d而不适用于s['store']

2 个答案:

答案 0 :(得分:3)

shelvepickle(序列化)对象。必要时,这是一个副本。因此,从shelve返回的对象与您输入的对象不具有相同的标识,尽管它们是等效的。

如果它很重要,你可以编写一个deque子类,它会在修改时自动重新架设,尽管在许多用例中这可能会有很差的性能。

答案 1 :(得分:2)

事实证明它们并不相同,因此您对它们执行的任何操作都不匹配:

>>> import shelve
>>> s = shelve.open('TestShelve')
>>> from collections import deque
>>> s['store'] = deque()
>>> d = s['store']
>>> id(s['store'])
27439296
>>> id(d)
27439184

要在编码时修改项目,您需要传递参数writeback=True

s = shelve.open('TestShelve', writeback=True)

参见文档:

  

如果writeback参数为True,则对象将保存缓存   访问所有条目并在同步和关闭时将它们写回dict   倍。这允许对可变条目进行自然操作,但可以   消耗更多的内存并使同步和关闭需要很长时间。

您也可以使用writeback=False执行此操作,但是您需要完全按照提供的示例编写代码:

# having opened d without writeback=True, you need to code carefully:
temp = d['xx']      # extracts the copy
temp.append(5)      # mutates the copy
d['xx'] = temp      # stores the copy right back, to persist it