10

ポインターの概念があるため、ほとんどの場合、C++ でコピー コンストラクター (またはオーバーロードされた代入演算子) を実装するのは簡単です。ただし、Python で浅いコピーと深いコピーを実装する方法については、かなり混乱しています。

ライブラリの 1 つに特別なコマンドがあることは知っていますが、自分で作成したクラスでは機能しません。では、実装する一般的な方法は何ですか?

PSいくつかの基本的なデータ構造(リンクされたリストまたはツリー)のプロセスを示すことは高く評価されます。

編集:ありがとう、彼らは働いた、それは構文の私の間違いでした。__copy__()これらの関数をandで上書きすることに非常に興味があります__deep_copy()__。例えば。データ構造に含まれる情報の種類を知らずにディープ コピーを作成するにはどうすればよいですか?

4

1 に答える 1

24

pythoncopyモジュールは、クラスがコピー動作をカスタマイズできるようにするために、pickleモジュールインターフェイスを再利用できます。

カスタム クラスのインスタンスのデフォルトでは、新しい空のクラスを作成し、属性を交換します。その後、浅いコピーの場合は、コピーの を元の値で__class__更新するだけです。__dict__ディープ コピーは__dict__代わりに再帰します。

__getstate__()それ以外の場合は、内部状態を返すメソッドを指定します。__setstate__()これは、クラスが再度受け入れることができる任意の構造にすることができます。

__copy__()and/or__deepcopy__()メソッドを指定して、コピー動作のみを制御することもできます。これらのメソッドは、自分自身ですべてのコピーを行うことが期待されており、メソッドには再帰呼び出し__deepcopy__()に渡すためのメモ マッピングが渡されます。deepcopy()

例は次のとおりです。

from copy import deepcopy

class Foo(object):
    def __init__(self, bar):
        self.bar = bar
        self.spam = expression + that * generates - ham   # calculated

    def __copy__(self):
        # self.spam is to be ignored, it is calculated anew for the copy
        # create a new copy of ourselves *reusing* self.bar
        return type(self)(self.bar)

    def __deepcopy__(self, memo):
        # self.spam is to be ignored, it is calculated anew for the copy
        # create a new copy of ourselves with a deep copy of self.bar
        # pass on the memo mapping to recursive calls to copy.deepcopy
        return type(self)(deepcopy(self.bar, memo))

この例では、カスタム コピー フックを定義しself.spamて、新しいインスタンスが新たに計算するため、コピーも防止します。

于 2013-03-28T14:52:44.013 に答える