実際には、何を上書きするかを決定する要因(たとえば、__copy__
または__deepcopy__
)がクラスの望ましい動作に依存します。一般copy.deepcopy
に
は、ほとんどが正常に動作しますが、それだけでコピーすべて(recursivly)ので、あなただけががコピーされてはならないことを、いくつかの属性がある場合、それを上書きする必要があります(今までが!)。
一方、ユーザー(自分自身を含む)がコピーされたインスタンスに変更が反映されることを期待しない場合のみ、__copy__
を定義する必要があります。たとえば、変更可能な型(例:list
)をラップするか、変更可能な型を実装の詳細として使用するだけです。
コピーする属性の最小限のセットが明確に定義されていない場合もあります。その場合、私はまた__copy__
をオーバーライドするかもしれませんが、おそらくそこにTypeError
を上げ、可能な1つ(または複数)の専用公開copy
メソッドを含めることができます。
しかし私の意見ではarr
実装の詳細としてカウントとは、このように私は__copy__
オーバーライドします:
class T(object):
def __init__(self, x, y):
self.arr = [x, y]
def __copy__(self):
new = self.__class__(*self.arr)
# ... maybe other stuff
return new
はちょうどそれが期待どおりに動作を示すために:ちょうど簡単なメモ
from copy import copy, deepcopy
x = T([2], [3])
y = copy(x)
x.arr is y.arr # False
x.arr[0] is y.arr[0] # True
x.arr[1] is y.arr[1] # True
x = T([2], [3])
y = deepcopy(x)
x.arr is y.arr # False
x.arr[0] is y.arr[0] # False
x.arr[1] is y.arr[1] # False
約期待値:
ユーザーは一般的に帽子を使用すると、コンストラクタにインスタンスを渡して最小限のコピー(__copy__
と同様または同一)を作成することができます。たとえば:
lst1 = [1,2,3,4]
lst2 = list(lst1)
lst1 is lst2 # False
いくつかのPythonの型は、(存在する場合は)__copy__
と同じ操作を行う必要があることを明示的copy
方法を、持っています。それは(ただし、私はまだこの動作を見ていない)、明示的にパラメータを渡すことができます:
lst3 = lst1.copy() # python 3.x only (probably)
lst3 is lst1 # False
あなたのクラスは他のユーザーによって使用されるべき場合は、おそらくあなただけしたいがあれば、これらの点を考慮する必要がありますあなたのクラスをcopy.copy
で動作させると、__copy__
を上書きするだけです。
「深い」という概念は、再帰的な部分から来ています。そうでなければ、「深いコピーは新しい複合オブジェクトを構成し、それに深いコピーを挿入します」と再帰的な記述です。 –