Python-Variablenumfang (Weitergabe über Referenz oder Kopie?)

7

Warum wird die Variable L im Funktionsaufruf sorting(L) manipuliert? In anderen Sprachen würde eine Kopie von L als Kopie an sorting() übergeben, so dass Änderungen an x die ursprüngliche Variable nicht ändern würden.

%Vor%     
Ryan 08.03.2011, 14:57
quelle

4 Antworten

11

Kurz gesagt: Python verwendet Pass-by-Value, aber die Dinge, die als Wert übergeben werden, sind Verweise. Die tatsächlichen Objekte weisen Referenzen von 0 bis unendlich auf, und zum Zwecke der Mutation dieses Objekts ist es egal, wer Sie sind und wie Sie eine Referenz auf das Objekt erhalten haben.

Gehen Sie Schritt für Schritt durch Ihr Beispiel:

  • L = [...] erstellt ein list -Objekt irgendwo im Speicher, die lokale Variable L speichert eine Referenz auf dieses Objekt.
  • sorting (genauer gesagt, das aufrufbare Objekt, auf das der globale Name sorting verweist) wird mit einer Kopie des von L gespeicherten Verweises aufgerufen und in einem lokalen namens x .
  • gespeichert
  • Die Methode sort des Objekts, auf das der in x enthaltene Verweis verweist, wird aufgerufen. Es erhält auch eine Referenz auf das Objekt (im Parameter self ). Es mutiert irgendwie das Objekt ( das Objekt , nicht irgendeine Referenz auf das Objekt, die lediglich mehr als eine Speicheradresse ist).
  • Nun, da Referenzen kopiert wurden, aber nicht das Objekt, auf das die Referenzen verweisen, verweisen alle anderen Referenzen, die wir besprochen haben, immer noch auf dasselbe Objekt. Das eine Objekt, das "in-place" geändert wurde.
  • testScope gibt dann einen weiteren Verweis auf dieses Listenobjekt zurück.
  • print verwendet es, um eine Zeichenfolgendarstellung anzufordern (ruft die Methode __str__ auf), und gibt sie aus. Da es immer noch dasselbe Objekt ist, druckt es natürlich die sortierte Liste.

Wenn Sie also ein Objekt irgendwo passieren, teilen Sie es mit demjenigen, der es erhält. Funktionen können die Objekte (die auf die Referenzen verweisen), an die sie übergeben werden, mutieren (aber normalerweise nicht), indem sie mutierende Methoden auf die Zuweisung von Mitgliedern anwenden. Beachten Sie jedoch, dass die Zuweisung eines Mitglieds nicht mit der Zuweisung eines einfachen Namens übereinstimmt. Dies bedeutet lediglich, dass Sie den lokalen Bereich mutieren müssen und nicht die Objekte des Aufrufers. Sie können also die Ortsnamen des Anrufers nicht mutieren (deshalb ist es nicht Pass-by-Reference).

Weiterführende Literatur: Eine Diskussion über effbot.org warum es nicht Pass-by-Reference ist und nicht was die meisten Leute pass-by-value nennen würden.

    
delnan 08.03.2011, 15:09
quelle
8

Python hat das Konzept von Mutable und unveränderlichen Objekten . Ein Objekt wie eine Zeichenfolge oder eine Ganzzahl ist unveränderlich - jede Änderung, die Sie vornehmen, erstellt eine neue Zeichenfolge oder Ganzzahl.

Listen sind veränderbar und können an Ort und Stelle manipuliert werden. Siehe unten.

%Vor%

Beachten Sie, wie c umgekehrt wurde, weil c "ist" a. Es gibt viele Möglichkeiten, eine Liste in ein neues Objekt im Speicher zu kopieren. Eine einfache Methode ist das Slice: c = a[:]

    
lunixbochs 08.03.2011 15:09
quelle
1

Es wird speziell in der Dokumentation erwähnt, dass die Funktion .sort() die Sammlung mutiert. Wenn Sie über eine sortierte Sammlung iterieren möchten, verwenden Sie stattdessen sorted(L) . Dies stellt einen Generator zur Verfügung, anstatt nur die Liste zu sortieren.

    
Exelian 08.03.2011 15:05
quelle
0
%Vor%

Referenzen sind nicht identisch mit separaten Objekten.

.sort() mutiert auch die Sammlung.

    
Jakob Bowyer 08.03.2011 15:02
quelle

Tags und Links