使用pickle进行内存中的“事务”?
用户可以执行一个操作,这可能会触发相关操作(这些操作本身可能具有相关操作),并且如果用户取消相关操作,我希望能够取消整个操作。
我见过的典型方法是撤消堆栈的某种变体,每个操作都需要知道如何撤消自身,然后如果子操作被取消,则撤消会级联向上。有时,编写撤消方法很棘手,并且上下文中并不总是有足够的信息来正确了解如何以隔离的方式撤消操作。
我只是想到了一种(可能)更简单的方法,即仅pickle
程序(相关部分)的状态,然后取消将恢复到以前的状态,而不需要创建单独的状态撤消每个操作的逻辑。
有人试过这个吗?有什么需要注意的问题吗?有什么理由不这样做呢?
编辑:依赖操作必须在父操作之后发生(甚至是否存在依赖操作可能取决于父操作的结果),因此在执行任何操作之前仅检查所有依赖项不是一种选择。我想你可能会说一个动作会触发其他动作,但如果其中一个触发的动作无法执行,那么就什么都不会发生。
A user can perform an action, which may trigger dependent actions (which themselves may have dependent actions) and I want to be able to cancel the whole thing if the user cancels a dependent action.
The typical way I've seen this done is some variant of an undo stack and each action will need to know how to undo itself, and then if a child action is cancelled the undo's cascade their way up. Sometimes writing undo methods are tricky and there isn't always enough information in context to properly know how to undo an action in an isolated manner.
I just thought of a (potentially) easier way which is to just pickle
the state of the (relevant parts of) program, and then the cancel would just restore to it's former state, without needing to create separate undo logic for each action.
Has anyone tried this? Any gotchas to watch out for? Any reason not to do this?
Edit: The dependent actions must happen after the parent action (and even whether there are dependent actions may depend on the result of the parent action), so just checking all the dependencies before doing anything isn't an option. I guess you could say an action triggers other actions, but if one of the triggered actions cannot be performed, then none of it happened.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,正如您提到的,数据设计是松散耦合的,所以如果它在内存中,我认为您不需要对其进行pickle。只需复制所有相关变量,
transaction.abort()
就会将它们复制回来,transaction.commit()
就会删除数据。虽然存在一些问题,但使用 pickle 解决方案时,没有一个问题是不存在的。
Well, as you mentioned the data design is loosely coupled, so you I don't think you need to pickle it if it's in memory. Just take a copy of all the relevant variables, and the
transaction.abort()
would just copy them back, andtransaction.commit()
would then just remove the copy of the data.There are issues, but none that you don't have with the pickle solution.
如果状态的所有元素都是可序列化的(通常是),则可以使用 pickle 来存储状态。不这样做的唯一原因是:
如果您必须存储指向未保存在状态中的任何对象的指针,那么在执行撤消操作后,这些指针将会出现问题。
此方法可能会很昂贵,具体取决于您所在州的大小。
您还可以使用 zip() 来降低内存使用率,以换取提高 CPU 使用率。
You can use pickle to store your state if all elements of state are serializable (usually they are). The only reasons for not doing so:
if you have to store pointers to any objects that are not saved in state, you will have problems with these pointers after performing undo operation.
this method could be expensive, depending on the size of your state.
Also you can use zip() to lower memory usage in exchange of raising CPU usage.