Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erläuterung des flachen Kopier-, Deep-Copy- und Referenzmechanismus von Python

Detaillierte Erläuterung des flachen Kopier-, Deep-Copy- und Referenzmechanismus von Python

高洛峰
高洛峰Original
2017-03-23 17:43:071491Durchsuche

Ich bin diese Woche auf einige Probleme gestoßen, und dann wurde mir klar, dass es immer noch vergessene Teile gibt, die noch überprüft werden müssen, wenn das Grundwissen eine Weile nicht gefestigt wurde. Ich werde es hier notieren, um es aufzuzeichnen

Zuvor

Beschreiben Sie zunächst kurz das aufgetretene Problem. Die Anforderung besteht darin, die Ergebnisse von 2 Drucken zu schreiben

详解Python浅拷贝、深拷贝及引用机制

Wie Wie Sie sehen, zeigt a auf ein Listenobjekt. In Python bedeutet eine solche Zuweisungsanweisung tatsächlich, dass a auf die Speicheradresse zeigt, an der sich die Liste befindet, was als Konzept ähnlich einem Zeiger betrachtet werden kann.

Und b, beachten Sie, dass es das a-Objekt in eine Liste einschließt und es mit 5 multipliziert, sodass b wie eine große Liste mit allen darin enthaltenen Elementen aussehen sollte a

Und wenn ein Nachher Das Objekt wird angehängt, die implizite Bedeutung ist, dass die Liste im Speicher geändert wurde und alle Objekte, die auf dieses Objekt verweisen, sich ändern.

Ich drucke die ID von a aus und drucke gleichzeitig Die ID des Elements a, das im Objekt b enthalten ist, sodass Sie sehen können, dass in der Liste b die ID jedes Elements mit a identisch ist

详解Python浅拷贝、深拷贝及引用机制

Wir können sehen dass die ID (Speicheradresse) von Objekt a 10892296 ist. Obwohl b a in eine neue Liste einschließt, verweist dieses Element immer noch auf das Objekt mit derselben Adresse. Dies kann durch die folgende Abbildung erklärt werden

详解Python浅拷贝、深拷贝及引用机制

Danach haben wir die Anhängeoperation für a durchgeführt. Da es sich bei der Liste um ein Variablenobjekt handelt, hat sich seine Speicheradresse nicht geändert. Für diese Adresse im Speicher werden jedoch alle referenzierten Objekte gemeinsam geändert

Dies führt zu einer Überprüfung des Python-Referenzmechanismus und des flachen Kopierens und des tiefen Kopierens

Pythons Referenzmechanismus



Referenzmechanismus Fall 1

Aus dem obigen Beispiel können wir sehen, dass Python Das Endergebnis ist, dass beide Objekte darauf verweisen der Inhalt desselben Bereichs im Speicher

Schauen wir uns also das folgende Beispiel an

B übergibt A und referenziert auch die ID 17446024 Der Inhalt der Adresse und die ID (Speicheradresse). ) der beiden sind genau gleich

Durch die Operation A A[0]=3 oder A[3].append(6) wird also der Inhalt dieses Speichers geändert (da die Liste ist Bei einem variablen Objekt ändert sich die Speicheradresse nicht, wir werden später darüber sprechen)

Dies ist der grundlegendste Referenzfall (außerdem, da A und B beide auf dieselbe Speicheradresse verweisen, also auf den Inhalt modifiziert durch B kann auch auf A reflektiert werden)

详解Python浅拷贝、深拷贝及引用机制

Referenzmechanismus Fall 2

Sehen wir uns einen anderen Fall an

Wenn man sich die Frage ansieht, scheint es, dass Element 2 durch die Liste selbst ersetzt wird. Das Ergebnis könnte A=[1,[1,2,3],3] sein

Aber das ist nicht der Fall! ! Sie können sehen, dass es unendlich viele verschachtelte

im roten Feld gibt. Warum ist das so?

Tatsächlich liegt es daran, dass A auf die Liste [1,2,3] zeigt. In diesem Beispiel zeigt nur das zweite Element von A auf das A-Objekt selbst, also ist es nur das zweite Element von A. Die Struktur hat sich geändert! Allerdings zeigt A immer noch auf dieses Objekt

Wir können durch Drucken der ID von A sehen, dass sich seine Ausrichtung nicht geändert hat! !

详解Python浅拷贝、深拷贝及引用机制

Sehen Sie, die Richtung von A hat sich nicht geändert

详解Python浅拷贝、深拷贝及引用机制

Wenn wir dann den endgültigen Ausgabeeffekt erzielen wollen, ist das der Fall [ 1, [1,2,3],3], wie sollen wir es bedienen?

Hier verwenden wir flache Kopie. Die Verwendung kann wie folgt sein:


详解Python浅拷贝、深拷贝及引用机制

Flache Kopie und tiefe Kopie

Flache Kopie

Lassen Sie uns nun über flaches Kopieren und tiefes Kopieren sprechen. Die obige Methode führt eigentlich nur flache Kopien durch, was bedeutet, dass sie das ursprünglich referenzierte Objekt kopiert, aber nicht mehr auf dieselbe Objektadresse verweist

Schauen Sie sich das folgende Beispiel an. B führt eine flache Kopie durch die Operation B = A[:] aus. Sie können sehen, dass nach der flachen Kopie die von A und B referenzierten Speicheradressen bereits unterschiedlich sind Die Referenzadressen der Elemente in A und B sind immer noch dieselben. Seien Sie also sehr vorsichtig! Es gibt einen Unterschied! ! !

Der Unterschied in den Referenzspeicheradressen von A und B bedeutet, dass die Operation, die Sie an B ausführen, keine Auswirkungen auf A hat.



详解Python浅拷贝、深拷贝及引用机制
Zusammenfassung der flachen Kopie:
Die flache Kopie kann also als Kopieren einer Referenz, des neuen Objekts und des Originals zusammengefasst werden. Die Referenzen zu den Objekten werden unterschieden, aber die Adressreferenzen der internen Elemente sind immer noch dieselben

Aber auch flaches Kopieren verursacht Probleme. Was ist das Problem? Dies ist der Fall, wenn eine Verschachtelung vorliegt. Wie Sie beispielsweise in der folgenden Situation sehen können, habe ich B eine flache Kopie von A zugewiesen, sodass die IDs (Speicheradressen) von A und B unterschiedlich sind.

Wenn ich also A[0]=8 ändere, ist B nicht betroffen, da A und B unabhängige Referenzen sind, es aber eine verschachtelte Liste in der Mitte gibt [4 ,5,6]

Wir können dies [4,5,6] so verstehen: A und B verweisen immer noch aufeinander, das heißt, für die zweiten Elemente von A und B verweisen sie immer noch auf dieselbe A-Speicheradresse.

Da int außerdem ein unveränderlicher Typ ist, ändert sich nach der Änderung von A[0] in 8 seine Referenzadresse! Es unterscheidet sich von der Referenz des Elements B[0].



详解Python浅拷贝、深拷贝及引用机制
Deep Copy
Wie kann man also mit einer solchen Situation umgehen? Sie müssen das Kopiermodul im Python-Modul verwenden

Das Kopiermodul hat zwei Funktionen

1: copy.copy (das Objekt, das Sie kopieren möchten): Dies ist eine flache Kopie und die vorherige Die Eigenschaften der [:]-Operation in der Liste sind dieselben

2: copy.deepcopy (das Objekt, das Sie kopieren möchten): Dies ist eine tiefe Kopie, mit der Ausnahme, dass eine neue erstellt wird Objekt genau wie die flache Kopie, und für interne Elemente werden neue Referenzen generiert, um sie unabhängig voneinander zu trennen.

Sehen Sie sich das Beispiel unten an Es wird gesagt, dass es völlig unabhängig ist. Unabhängig davon, ob Sie die unveränderlichen Elemente in A oder die verschachtelten veränderlichen Elemente in A ändern, hat das Ergebnis keinen Einfluss auf B.

Mein Verständnis ist: Eine tiefe Kopie kann als rekursive Kopie bezeichnet werden Kopieren Sie alle verschachtelten Variablenelemente und referenzieren Sie sie dann unabhängig voneinander.



详解Python浅拷贝、深拷贝及引用机制
Deep Copy-Zusammenfassung:
Der Effekt von Deep Copy ist der gleiche B. das der flachen Kopie. Zusätzlich zum Generieren einer neuen Referenz aus der Objektreferenz hilft es Ihnen, alle verschachtelten Elemente einzeln zu trennen.

Zeichnung 2 von mir selbst, um den Unterschied zwischen flacher Kopie und zu zeigen tiefes Kopieren

Es ist zu beachten, dass die Referenzadresse der unveränderlichen Elemente in der Liste zwar nach dem flachen Kopieren immer noch dieselbe ist, aber da es sich um unveränderliche Elemente handelt, wird die Referenz nach jeder Änderung eines unveränderlichen Elements geändert Die Adresse ist neu, ohne dass sich dies auf die ursprüngliche Referenzadresse auswirkt.





详解Python浅拷贝、深拷贝及引用机制

详解Python浅拷贝、深拷贝及引用机制
Zusammenfassung
So, los geht's, oberflächlich copy Und der Mechanismus des Deep Copy ist grundsätzlich verstanden.

Es gibt auch besondere Umstände, die erklärt werden müssen

Für unveränderliche Typen: int, str, tuple, float und andere Elemente gibt es keine Kopie, nachdem sie geändert wurden, die Referenzadresse wird direkt geändert, wie unten gezeigt



详解Python浅拷贝、深拷贝及引用机制 Wenn sich jedoch verschachtelte Variablentypen innerhalb des unveränderlichen Typs befinden, können Sie weiterhin Deep Copy

verwenden详解Python浅拷贝、深拷贝及引用机制

Auch zur Erinnerung: Die am häufigsten verwendete Methode ist die direkte Zuweisung (oder direkte Übergabe von Referenzen), wie im folgenden Beispiel.

Er kombiniert a und b. Zwei variable Elemente zeigen auf eine Speicheradresse gleichzeitig, sodass sich jede Änderung auf a und b auswirkt

详解Python浅拷贝、深拷贝及引用机制

Schließlich

Variablentyp: list , set, dict

unveränderliche Typen: int, str, float, tuple

Methode für flaches Kopieren: [:], copy.copy(), Factory-Funktion verwenden (list/dir/set)

Tiefe Kopie Methode: copy.deepcopy()


Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des flachen Kopier-, Deep-Copy- und Referenzmechanismus von Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn