Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何构建具有限制的撤消存储?_Python_Storage_Undo_Fifo - Fatal编程技术网

Python 如何构建具有限制的撤消存储?

Python 如何构建具有限制的撤消存储?,python,storage,undo,fifo,Python,Storage,Undo,Fifo,我想构建一个数据结构来存储有限的撤销缓冲区,以存储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 l

我想构建一个数据结构来存储有限的撤销缓冲区,以存储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.
我的问题是,现有的buildin数据类型或标准库类型是否可以用于此目的

这种结构是否可能在一个结构实例中存储多个类型,比如说,如果我想一次性存储dict和自定义类

谢谢

Rgs


KC包含一个撤销架构。也许你可以研究一下,弄清楚他做了什么,甚至可以开箱即用。

包含一个撤销架构。也许你可以研究一下,弄清楚他做了什么,甚至可以开箱即用。

也许可以这样使用:

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]
创建一个未撤消的缓冲区对象

rawdict=UndoBuffer('{1}')      
设置
数据
属性会自动将值存储在
\u缓冲区中

print(rawdict._buffer)
# deque(['{1}'], maxlen=5)
print(rawdict.data)
# {1}
rawdict.data = '{2}'
print(rawdict._buffer)
# deque(['{1}', '{2}'], maxlen=5)
更改
rawdict.data
的值会将该值附加到
rawdict.\u buffer

print(rawdict._buffer)
# deque(['{1}'], maxlen=5)
print(rawdict.data)
# {1}
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.\u缓冲区还原值:

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)

也许可以这样使用:

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]
创建一个未撤消的缓冲区对象

rawdict=UndoBuffer('{1}')      
设置
数据
属性会自动将值存储在
\u缓冲区中

print(rawdict._buffer)
# deque(['{1}'], maxlen=5)
print(rawdict.data)
# {1}
rawdict.data = '{2}'
print(rawdict._buffer)
# deque(['{1}', '{2}'], maxlen=5)
更改
rawdict.data
的值会将该值附加到
rawdict.\u buffer

print(rawdict._buffer)
# deque(['{1}'], maxlen=5)
print(rawdict.data)
# {1}
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.\u缓冲区还原值:

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)

您无法在裸名上执行此操作(例如
rawdict1
),因为您无法截取对裸名的赋值,并让它们在“一边”执行某些操作,例如保存以前的值。在修饰过的名字上很容易做到,例如:

undoable.rawdict1 = {1}

诸如此类,通过使
可撤消
类的实例具有适当的
\uuuu setitem\uuuu
,该类将先前的值(如果有)附加到列表中,并且如果列表变得太长,则弹出第0项。但这不足以满足除赋值之外的其他“可撤消”操作,例如
undoable.rawdict1.update(无论什么)
——您确定不需要它吗?

您不能在一个裸名上执行它(例如
rawdict1
),因为您无法截取对裸名的赋值,并让它们在某个时间“在一旁”执行例如保存上一个值。在修饰过的名字上很容易做到,例如:

undoable.rawdict1 = {1}

诸如此类,通过使
可撤消
类的实例具有适当的
\uuuu setitem\uuuu
,该类将先前的值(如果有)附加到列表中,并且如果列表变得太长,则弹出第0项。但这对于除赋值之外的其他“可撤消”操作来说是不够的,例如
可撤消的.rawdict1.update(无论什么)
——您确定不需要它吗?

您可以快速将列表子类化,只允许有限的存储

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

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

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

从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

从Python2.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

我想你已经超出了OP需要的两步了。:-)一、 对于我自己来说,当一个“可撤销的”类装饰器可能很方便时,我会记住这个答案的!:-)谢谢Alex,很高兴看到你再次给出答案。这里可能不是一个具有内置撤消操作的容器类,我想要一个容器作为具有撤消功能的数据流的法兰:它可能看起来是这样的:数据消费者撤消容器数据源***如果我直接对数据源进行操作,数据消费者可能会更改数据源,但没有对数据源进行恢复的更改,然后我需要一个缓冲区和撤销机会。而rawdata1是来自外部的数据,也许我必须制作一个deepcopy,然后将它们推送到undo类中?@registed,如果你可以在任何给定的、重要的点上作为一个显式操作进行推送,而不是通过分配给一个可撤销的名字隐式地进行推送,那么你的生活肯定会更简单;-)。注意到了,谢谢Alex,我知道我是编程的初学者,然后我仍然需要大家的帮助,特别是那些我可以轻松理解的基本部分;-)。我想你已经超出了OP需要的两步了。:-)一、 对于我自己来说,当一个“可撤销的”类装饰器可能很方便时,我会记住这个答案的!:-)谢谢Alex,很高兴看到你再次给出答案。这里可能不是一个具有内置撤消操作的容器类,我想要一个容器作为具有撤消功能的数据流的法兰:它可能看起来是这样的:数据消费者撤消容器数据源***如果我直接对数据源进行操作,数据消费者可能会更改数据源,但没有对数据源进行恢复的更改,然后我需要一个缓冲区和撤销机会。而rawdata1是来自外部的数据,也许我必须制作一个deepcopy,然后将它们推送到undo类中?@registed,如果你可以在任何给定的、重要的点上作为一个显式操作进行推送,而不是通过分配给一个可撤销的名字隐式地进行推送,那么你的生活肯定会更简单;-)。注意到了,谢谢Alex,我知道我是编程的初学者,然后我仍然需要大家的帮助,特别是那些我可以轻松理解的基本部分;-)。然而,对于我来说,它可能有点大,因为我的快速解决方案。我只需要一个存储器,可以存储5个原始数据副本,并为它们分配索引