2

前提: Python object が与えられた場合obj、それをランダムな関数に渡したいと思います。関数が完了したら、obj元の状態にリセットするオプションが必要です。objさらに、他のコードが元の状態にアクセスする可能性があるため、実際の変更を行うことはできません。


最適なソリューションは、大規模なobjものがわずかに変更された一般的なケースでは迅速に行われる必要があります。objをロールバックする必要があるまれなケースのパフォーマンスはそれほど重要ではありません。

これらの要件は、単純にオブジェクトをコピーするというブルート フォース ソリューションとは直交しています。一般的なケースでは途方もなく遅く、まれなロールバックでは非常に高速です。

通常、このソリューションでは、オブジェクトを処理するコードがオブジェクトを通常のオブジェクトとして処理できるようにする必要があります。これには、カスタム クラスを含むあらゆる種類の属性の割り当てが含まれます。明らかに、ソリューションではオブジェクト ツリー全体を考慮する必要があります。いくつかの譲歩が必要な場合があります。これまでのソリューションで検討した制限の例には、非基本型がすべて特別な基本クラスから継承することを要求すること、タプルとカスタム dict クラスと引き換えに dict とリストを許可しないことが含まれます。大アルカナは許容される場合があります。

私はこれにしばらく取り組んできましたが、経験豊富な Python ウィザードがどのようなアイデアや提案を持っているかを知りたいと思っています。


編集:フレッドの答えにより、要件が欠落していることに気付きました:obj元の状態も価値があるため、元に変更を加えることはできません。

4

2 に答える 2

1

私は実際にこの質問に対して2つの解決策を実装しましたが、他に答えがないので、1つを共有したほうがよいでしょう。

最も簡単な解決策は、CopyOnDemandを使用することです。プロキシPターゲティングオブジェクトがある場合O:試行されたときに、からコピーを試み、同時に保存するメソッドPがあります。これには、の将来のアクセスが到達しないという効果があり、への変更は元のに影響を与えません。__getattr__P.xO.xP.xP.x__getattr__P.x

実装の詳細はたくさんあります。

  • から削除される属性のリストを維持するP; Pとマージする場合O、削除された属性をから削除する必要がありますO
  • 、などのサポートされているデータ型のカスタムディープコピールーチンを作成します。コピーされたdict、などの すべてのオブジェクトをプロキシにlist置き換えてください。OPdictlist
  • 必要に応じて 書き込みProxyDictなど。ProxyList
  • プロキシチェーン、つまりプロキシからプロキシへのプロキシが機能することを確認します。これは基本的に、プロキシへのプロキシが属性が存在するかどうかを確認する必要がある場合の副作用を回避することを意味します。
  • プロキシを下向きにプロキシされたオブジェクトにマージし、それを完全に分割して、プロキシされたオブジェクトから残りのデータをコピーするためのメソッドを実装します。

    それでも、効果の複雑さに比べて、非常に理解しやすい解決策です。プロキシは、アクセスされたデータをコピーするだけです。

  • 于 2011-02-03T13:12:09.050 に答える
    0

    Mementoデザインパターンを見てみましょう

    これがPythonの例です

    于 2011-01-27T16:43:02.513 に答える