2013-03-28 12 views
10

Es ist in den meisten Situationen einfach, Kopierkonstruktoren (oder überladene Zuweisungsoperatoren) in C++ zu implementieren, da es ein Konzept von Zeigern gibt. Ich bin jedoch ziemlich verwirrt darüber, wie man flache und tiefe Kopien in Python implementiert.Python: Implementierung von seichten und tiefen Kopierkonstruktoren

Ich weiß, dass es spezielle Befehle in einer der Bibliotheken gibt, aber sie arbeiten nicht mit Klassen, die Sie selbst geschrieben haben. Was sind die üblichen Wege zur Implementierung?

P.S. Das Anzeigen eines Prozesses für einige grundlegende Datenstrukturen (verknüpfte Liste oder Struktur) wird geschätzt.

EDIT: Danke, sie haben funktioniert, es war mein Fehler in der Syntax. Ich bin sehr daran interessiert, diese Funktionen mit __copy__() und __deep_copy()__ zu überschreiben. Beispielsweise. Wie kann ich eine tiefe Kopie erstellen, ohne zu wissen, welche Art von Information in einer Datenstruktur enthalten ist?

+5

Was meinen Sie, dass Bibliotheken nicht an Klassen arbeiten, die Sie selbst entworfen haben? Was ist falsch mit 'copy.copy' und' copy.deepcopy'? –

Antwort

22

Das Python copy module kann die pickle module Schnittstelle wiederverwenden, damit Klassen das Kopierverhalten anpassen können.

Die Standardeinstellung für Instanzen von benutzerdefinierten Klassen ist eine neue, leere Klasse zu erstellen, tauschen das __class__ Attribut, dann für flache Kopien, aktualisieren Sie einfach die __dict__ auf der Kopie mit den Werten aus dem Original. Eine tiefe Kopie rekursiert stattdessen über die __dict__.

Andernfalls geben Sie eine __getstate__() Methode an, um den internen Status zurückzugeben. Dies kann jede Struktur sein, die Ihre Klasse __setstate__() erneut akzeptieren kann.

können Sie auch angeben, die __copy__() und/oder __deepcopy__() Methoden nur Kopie Verhalten zu steuern. Von diesen Methoden wird erwartet, dass sie alle selbst kopieren, wobei die __deepcopy__()-Methode ein Memo-Mapping übergeben wird, das an rekursive deepcopy() Aufrufe weitergeleitet wird.

könnte ein Beispiel sein:

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)) 

Dieses Beispiel definiert Haken individuelle Kopie zu verhindern self.spam auch kopiert werden, wie eine neue Instanz es neu berechnen wird.

+0

Ich bin sehr an der letzten Lösung interessiert. Wie kann ich einen Wert aus einem anderen kopieren, ohne den Typ zu kennen? soll ich nur für alle Typen schreiben oder gibt es dafür eine einfachere Lösung? –

+1

@KudayarPirimbaev: Sie delegieren enthaltene Werte stattdessen an einen 'copy.deepcopy'-rekursiven Aufruf. Es wird verschiedene Arten behandeln. –

+0

danke, ich verstand den Punkt –