1

我想建立一个数据结构来存储有限的撤消缓冲区,以存储 6 dict 数据为例,下面的伪代码:

rawdict1 = {1}
buffer = [{1}]

rawdict1 = {2}
buffer = [{2}{1}]      # {1} stored on the postion

rawdict1 = {3}
buffer = [{3}{2}{1}]      
...
rawdict1 = {5}
buffer = [{5}{4}{3}{2}{1}]      # max length limited to 5

rawdict1 = {6}
buffer = [{6}{5}{4}{3}{2}]      # {1} has been deleted because exceed the limit

when I want to restore the rawdict1 later, I can use something looks like:

rawdict1 = buffer[5]                 # restore the 5th dict.

我的问题是,现有的内置数据类型或标准库类型可以用于这样的目的吗?

并且这样的结构是否有可能在一个结构实例中存储多种类型,例如,如果我想一次性存储 dict 和自定义类?

谢谢!

Rgs,

KC

4

5 回答 5

2

也许使用这样的东西:

import collections

class UndoBuffer(object):
    def __init__(self,value,max_length=5):
        self.max_length=max_length
        self._buffer=collections.deque([value],max_length)
    @property
    def data(self):
        return self._buffer[-1]
    @data.setter
    def data(self,value):
        self._buffer.append(value)
    def restore(self,index):
        self.data=self._buffer[index]

创建一个 UndoBuffer 对象

rawdict=UndoBuffer('{1}')      

设置data属性会自动将值存储在_buffer

print(rawdict._buffer)
# deque(['{1}'], maxlen=5)
print(rawdict.data)
# {1}

更改 的值rawdict.data会将值附加到rawdict._buffer

rawdict.data = '{2}'
print(rawdict._buffer)
# deque(['{1}', '{2}'], maxlen=5)

Buf 如果您访问rawdict.data,您只会获得最新的值:

print(rawdict.data)
# {2}

再更改几次值。当缓冲区填充到其最大长度时,“{1}”将被丢弃:

rawdict.data = '{3}'
rawdict.data = '{4}'
rawdict.data = '{5}'
print(rawdict._buffer)
# deque(['{1}', '{2}', '{3}', '{4}', '{5}'], maxlen=5)
rawdict.data = '{6}'
print(rawdict._buffer)
# deque(['{2}', '{3}', '{4}', '{5}', '{6}'], maxlen=5)

从 rawdict._buffer 恢复值:

rawdict.restore(0)   # set rawdict.data to rawdict._buffer[0]
print(rawdict.data)
# {2}
print(rawdict._buffer)
# deque(['{3}', '{4}', '{5}', '{6}', '{2}'], maxlen=5)
于 2010-08-02T02:38:52.537 回答
1

您不能在裸名(例如rawdict1)上执行此操作,因为您无法拦截对裸名的分配并让它们在某个时候“在旁边”执行,例如保存以前的值。在装饰名称上很容易做到,例如:

undoable.rawdict1 = {1}

等等,通过undoable使用适当的类创建一个实例,该实例__setitem__将先前的值(如果有)附加到列表中,如果列表变得太长,则弹出第 0 项。但这对于除分配之外的其他“可撤销”操作是不够的,例如undoable.rawdict1.update(whatever)——你确定你不需要那个吗?

于 2010-08-02T02:39:10.523 回答
1

您可以快速子类列表以仅允许有限的存储。

class LimitedStack(list):
 def __init__(self,limit=6):
    list.__init__(self)
    self.limit = limit

 def append(self,obj):
    if len(self) == self.limit:
        list.pop(self,0)
    list.append(self,obj)

Python 列表不必像 C# 中的通用列表那样属于某种类型。它们将存储您附加到它们的任何对象。

于 2010-08-02T02:48:45.287 回答
1

从 python 2.6 开始,集合模块包含“双端队列”集合。它的行为符合您的需要:

>>> import collections
>>> buffer = collections.deque([],6)
>>> buffer.extend(range(6))
>>> buffer
deque([0, 1, 2, 3, 4, 5], maxlen=6)
>>> buffer.append(6)
>>> buffer
deque([1, 2, 3, 4, 5, 6], maxlen=6)
>>> buffer[-1]
6
于 2010-08-02T02:56:38.663 回答
0

Rockford Lhotka 的 CSLA.NET 框架包含 Undo 架构。也许您可以研究它并弄清楚他做了什么,甚至可以开箱即用。

于 2010-08-02T02:37:33.240 回答