2

前提:给定一个 Python 对象obj,我想将它传递给一些随机函数,并且,当函数完成时,我需要重置obj为原始状态的选项。此外,不能对它进行实际更改,obj因为其他代码可能仍希望访问它的原始状态。


obj在一个大的只是稍微修改的常见情况下,最佳解决方案应该很快。obj需要回滚的罕见情况下的性能不太重要。

这些要求与简单地复制对象的蛮力解决方案是正交的:在常见情况下它会非常慢,而对于不常见的回滚来说却非常快。

该解决方案通常应允许处理对象的代码将其视为普通对象。这包括为其分配各种属性,包括自定义类。显然,解决方案需要考虑到整个对象树。可能需要一些让步。到目前为止,我在我的解决方案中考虑的限制示例包括要求非基本类型都继承自一个特殊的基类,不允许 dicts 和列表以换取元组和自定义 dict 类等。主要的奥秘是可以接受的。

我已经为此工作了一段时间,并且很想看看更有经验的 Python 向导是否有什么想法和建议。


编辑:Fred 的回答让我意识到了一个缺失的要求:不能对 original 进行任何更改obj,因为原始状态也很有价值。

4

2 回答 2

1

到目前为止,我实际上已经为这个问题实施了两种解决方案,鉴于没有其他答案,我不妨分享一个。

最简单的解决方案是使用Copy On Demand。如果我们有一个代理P目标对象O:P将有一个__getattr__方法,以便在P.x尝试时,它会尝试从 复制O.x,同时将其存储P.x。这样做的效果是以后的访问P.x永远达不到__getattr__,修改P.x不会影响原来的。

有一堆实现细节:

  • 维护从 中删除的属性列表P;如果P与 合并O,则必须从 中删除已删除的属性O
  • 为任何受支持的数据类型(例如 , 等)编写自定义深度复制例程dict-list确保用复制的, 等 中O的代理替换所有对象。Pdictlist
  • 写作ProxyDict等,ProxyList如果需要的话。
  • 确保代理链(即代理的代理)有效。这基本上意味着在代理的代理需要查看属性是否存在时避免副作用。
  • 实现将代理向下合并到代理对象的方法,并将其完全拆分,从代理对象复制剩余数据。

    即便如此,相比效果的复杂性,这是一个非常容易理解的解决方案:代理只是简单地复制任何被访问的数据。

  • 于 2011-02-03T13:12:09.050 回答
    0

    了解Memento设计模式

    这是python的一个例子

    于 2011-01-27T16:43:02.513 回答