如何建立一个有限制的undo存储?

发布于 2024-09-12 01:33:30 字数 666 浏览 13 评论 0原文

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

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

I want build a data structure to store limited undo buffer, take store 6 dict data for example with below pseudocode:

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.

My question is, can existing buildin data type or standard library type can be used for such a purpose?

And is it possible such a structure can store multi-types in one structure instance, say, if I want to store dict and self-defined class in one go?

Thanks!

Rgs,

KC

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

吃素的狼 2024-09-19 01:33:31

也许使用这样的方法:

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)

如果您访问 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)

Perhaps use something like this:

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]

Make an UndoBuffer object

rawdict=UndoBuffer('{1}')      

Setting the data attribute automatically stores the value in _buffer:

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

Changing the value of rawdict.data appends the value to rawdict._buffer:

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

Buf if you access rawdict.data you just get the most recent value:

print(rawdict.data)
# {2}

Change the value a few more times. '{1}' gets dropped when the buffer is filled to its maximum length:

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)

Restoring the value from 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)
ま昔日黯然 2024-09-19 01:33:31

您不能在裸名(例如 rawdict1)上执行此操作,因为您无法拦截对裸名的分配并让它们有时“在侧面”执行操作,例如保存以前的值。 可以很容易地对装饰名称进行操作,例如:

undoable.rawdict1 = {1}

通过使用附加的适当的 __setitem__ 使类的实例可撤销, 等将前一个值(如果有)添加到列表中,如果列表太长,则弹出第 0 个项目。但这对于除赋值之外的“其他可撤消”操作来说是不够的,例如 undoable.rawdict1.update(whatever) - 您确定不需要它吗?

You cannot do it on a barename (such as rawdict1) because there is no way for you to intercept assignments to a barename and make them do sometime "on the side" such as saving the previous value. It's easy to do on a decorated name, e.g.:

undoable.rawdict1 = {1}

and the like, by making undoable an instance of a class with an appropriate __setitem__ which appends the previous value (if any) to a list, and pops the 0th item if the list is getting too long. But that would not suffice for other "undoable" actions besides assignment, such as undoable.rawdict1.update(whatever) -- you sure you don't need that?

迷雾森÷林ヴ 2024-09-19 01:33:31

您可以快速对列表进行子类化,以仅允许有限的存储。

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# 中的通用列表那样属于某种类型。它们将存储您附加到它们的任何对象。

You can quickly subclass the list to only allow limited storage.

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 lists do not have to be of a certain type like the generic lists in C#. They will store any object you append to them.

帅冕 2024-09-19 01:33:31

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

>>> 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

The collections module, as of python 2.6, contains the "deque" collection. It behaves as you need:

>>> 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
ι不睡觉的鱼゛ 2024-09-19 01:33:31

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

Rockford Lhotka's CSLA.NET framework contains an Undo architecture. Perhaps you could study it and figure out what he did, or even use it out of the box.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文