Важный вопрос здесь, если вам нужно «отменить отмену»?)
В любом случае, я настоятельно рекомендую инкапсулировать логику в один класс, легко потеряться с логикой, когда вы манипулируете свободными объектами.
Допустим, вам не нужно отменятьотмена, немного схематичная реализация:
class QueueWithUndo:
def __init__(self, history=10):
self.q = deque()
self.undo_q = deque(maxlen=history)
def enqueue(self, task):
self.undo_q.append((self.q.pop, ))
self.q.append(task)
def pop(self):
result = self.q.popleft()
self.undo_q.append((self.q.append, result))
return result
def undo(self):
op, *task = self.undo_q.pop()
op(*task)
Идея проста - 1 дек для задач, 1 дек с ограниченным размером (или нет), который отслеживает, как "отменить" операции.Обычная очередь задач используется в качестве очереди FIFO - поэтому вы добавляете с одной стороны, а с противоположной.Отмена отмены используется в качестве LIFO / стека - последний контекст - это то, что используется для отмены вещей.
Хитрость заключается в том, что обычные и очереди превращаются в каждую операцию, также в качестве аргументов.Т.е. вам нужно сохранить контекст для pop отмены.