Es kommt tatsächlich auf das gewünschte Verhalten Ihrer Klasse an, das in die Entscheidung eingreift, was überschrieben werden soll (__copy__
oder __deepcopy__
).
Im Allgemeinen copy.deepcopy
arbeitet meist richtig, es ist einfach alles Kopien (rekursiv), so müssen Sie nur es außer Kraft zu setzen, wenn es eine Eigenschaft ist, dass darf nicht kopiert werden (je!).
Auf der anderen Seite sollte man __copy__
nur dann definieren, wenn Benutzer (einschließlich Sie selbst) nicht erwarten würden, dass Änderungen an kopierte Instanzen weitergegeben werden. Zum Beispiel, wenn Sie einfach einen veränderbaren Typ (wie list
) umbrechen oder änderbare Typen als Implementierungsdetails verwenden.
Dann gibt es auch den Fall, dass der minimale Satz von zu kopierenden Attributen nicht klar definiert ist. In diesem Fall würde ich auch __copy__
außer Kraft setzen, aber möglicherweise eine TypeError
dort erhöhen und möglicherweise eine (oder mehrere) dedizierte öffentliche copy
Methoden einschließen.
jedoch meiner Meinung nach die arr
zählt als Detail Umsetzung und somit würde ich __copy__
außer Kraft setzen:
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
einfach, es zu zeigen wie erwartet funktioniert:
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
Nur eine kurze Notiz über Erwartungen:
Benutzer erwarten im Allgemeinen t Außerdem können Sie eine Instanz an den Konstruktor übergeben, um eine minimale Kopie (ähnlich oder identisch mit __copy__
) zu erstellen. Zum Beispiel:
lst1 = [1,2,3,4]
lst2 = list(lst1)
lst1 is lst2 # False
Einiger Python-Typen haben ein expliziten copy
Verfahren, dass (falls vorhanden) als __copy__
das gleiche tun. Das würde erlauben ausdrücklich in Parameter übergeben (allerdings habe ich das noch nicht in Aktion gesehen):
lst3 = lst1.copy() # python 3.x only (probably)
lst3 is lst1 # False
Wenn Ihre Klasse von anderen verwendet werden, sollten Sie wahrscheinlich brauchen diese Punkte zu berücksichtigen, aber wenn Sie nur wollen Machen Sie Ihre Klasse mit copy.copy
arbeiten dann überschreiben Sie einfach __copy__
.
Das Konzept von "tief" kommt aus dem rekursiven Teil, sonst wäre eine rekursive Beschreibung "Eine tiefe Kopie erstellt ein neues zusammengesetztes Objekt und fügt dann tiefe Kopien hinein". –