@abc abstractproperty def can_undo(self)return bool(self __undos@abc abstractmethod def undo(self)assert self __undos"nothing left to undoself __undos pop()(selfdef add_undo(selfundo)self __undos append(undothe __init__(and undo(methods must be reimplemented since they are both abstractand so must the read-only can_undo property subclasses don' have to reimplement the add_undo(methodalthough they are free to do so the undo(method is slightly subtle the self __undos list is expected to hold object references to methods each method must cause the corresponding action to be undone if it is called--this will be clearer when we look at an undo subclass in moment so to perform an undo we pop the last undo method off the self __undos listand then call the method as functionpassing self as an argument (we must pass self because the method is being called as function and not as method here is the beginning of the stack classit inherits undoso any actions performed on it can be undone by calling stack undo(with no argumentsclass stack(undo)def __init__(self)super(__init__(self __stack [@property def can_undo(self)return super(can_undo def undo(self)super(undo(def push(selfitem)self __stack append(itemself add_undo(lambda selfself __stack pop()def pop(self)item self __stack pop(self add_undo(lambda selfself __stack append(item)return item