2012-04-20 8 views
6

私のクラスはさまざまなシステムの状態を表します。各インスタンスには2つの属性があります.1つは、同じシステムのすべての状態間で共有されるコンテナで、もう1つは各インスタンスに固有のコンテナです。copy vs deepcopy:意味

状態のコピーは、「共有」属性を再利用する必要がありますが、「一意」属性の詳細コピーを作成する必要があります。これは本当に意味をなさない唯一のコピーセマンティクスです(状態のコピーが同じシステムの状態であることは当然です)。

私のコードを読んだり維持している人には驚きを与えたくありません。自分の目的で__deepcopy__または__copy__を上書きする必要がありますか?

+0

'__deepcopy__'投票... –

+0

私はコンセンサスの見通しを望んでいました:)誰もがすべての人の反応を見る機会を得た後も、それはまだあるかもしれません。 – max

答えて

3

本当にこのクラスのインスタンスをコピーするためにコピーモジュールを使用する必要がありますか? __copy__または__deepcopy__を上書きする代わりに、定義したコピーセマンティクスを使用して新しいオブジェクトを返すクラスのメソッドcopyを作成する必要があります。

コピーモジュールを使用する必要がある一定の理由から、私の意見では__deepcopy__が適切です。すべてのインスタンスがコンテナの1つを共有するクラスの定義された振る舞いである場合、__deepcopy__の実装がそれを尊重すると仮定することは合理的です。

+0

私は 'copy'モジュールを使用していないので大丈夫です。しかし、 'copy'メソッドを定義すると、' dict'や 'set'のように、それが浅いコピーであると読者が想定しないでしょうか? – max

+0

@maxは、あなたのクラスは 'dict'または' set'のサブクラスですか?そうでなければ、読者はあなたのクラスの 'copy'メソッドが組み込み型から' copy'を真似ると仮定してはいけません。 –

+0

@max:意図したセマンティクスが完全に浅くも十分深くもないので、あなたはいつも読者を驚かせるでしょう。しかし、カスタムコピーセマンティクスを定義する可能性のある場所のうち、クラスの 'copy'メソッドは、カスタマイズされる可能性が最も高いメソッドだと思います。完全に浅く完全に深いセマンティクスが真に*あなたのクラスにとって理にかなっていないなら、なぜそれらの両方をオーバーライドしないのですか? ( '__copy__'と' __deepcopy__'はクラスの 'copy'を呼び出すことができます。) –

0

これはあなたの状況に似ていますか?

import copy 

class Foo(object): 
    shared = [[]] 
    def __init__(self): 
     self.perinstance = [[]] 

もしそうなら、あなたがcopy.deepcopy株式のクラス属性とdeepcopiesインスタンスのデフォルトの動作は、属性以来、__copy__または__deepcopy__を定義する必要はありません表示されます:あなたが服用している場合

x = Foo() 
z = copy.deepcopy(x) 
assert id(z.shared) == id(x.shared) 
assert id(z.shared[0]) == id(x.shared[0]) 
assert id(z.perinstance) != id(x.perinstance) 
assert id(z.perinstance[0]) != id(x.perinstance[0]) 
+0

残念ながら、私の共有属性はインスタンス属性です。私の説明には不正確でした。 「共有」属性は、異なるシステムに対応する場合にのみ、インスタンス間で異なる場合があります。コピーセマンティクスは、同じシステムからステートのコピーを作成するため、共有属性と同じ値を持ちます。私はこれを明確にするために質問を更新しています。 – max