Python Variable Scope (Vorbehalt durch Verweis oder Kopie?)

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

 def sorting(x): A = x #Passed by reference? A.sort() def testScope(): L = [5,4,3,2,1] sorting(L) #Passed by reference? return L >>> print testScope() >>> [1, 2, 3, 4, 5] 

4 Solutions collect form web for “Python Variable Scope (Vorbehalt durch Verweis oder Kopie?)”

Lange Geschichte kurz: Python verwendet Pass-by-Wert, aber die Dinge, die per Wert übergeben werden, sind Referenzen. Die eigentlichen Objekte haben 0 bis Unendlichkeit Referenzen auf sie, und für Zwecke der Mutation dieses Objekts, es spielt keine Rolle, wer du bist und wie bekamen Sie einen Verweis auf das Objekt.

Gehen Sie Schritt für Schritt durch Ihr Beispiel:

  • L = [...] erzeugt ein Listenobjekt irgendwo im Speicher, die lokale Variable L speichert einen Verweis auf dieses Objekt.
  • sorting (streng genommen, das kündbare Objekt, das als die globale sorting ) wird mit einer Kopie der von L gespeicherten Referenz aufgerufen und speichert sie in einem lokal genannten x .
  • Die Methode sort des Objekts, auf das durch die in x enthaltene Referenz hingewiesen wird, wird aufgerufen. Es bekommt auch einen Verweis auf das Objekt (im self ). Es mutiert dieses Objekt irgendwie ( das Objekt , nicht irgendein Verweis auf das Objekt, das nur mehr als eine Speicheradresse ist).
  • Nun, da Referenzen kopiert wurden, aber nicht das Objekt, auf das die Referenzen hindeuten, zeigen alle anderen Referenzen, die wir besprochen haben, noch auf dasselbe Objekt. Das eine Objekt, das "in-place" geändert wurde.
  • testScope dann einen weiteren Verweis auf dieses testScope zurück.
  • print verwendet es, um eine String-Darstellung anzufordern (ruft die __str__ Methode) auf und gibt sie aus. Da es immer noch das gleiche Objekt ist, druckt es natürlich die sortierte Liste.

Also, wann immer du ein Objekt irgendwo passierst, teile ich es mit jedem, der es wiedergibt. Funktionen können (aber normalerweise nicht) die Gegenstände mutieren (auf die Referenzen hinweisen), die sie übergeben werden, vom Aufrufen von Mutationsmethoden bis hin zu den Zuweisungsmitgliedern. Beachten Sie jedoch, dass die Zuweisung eines Mitglieds sich von der Zuweisung eines einfachen ol 'Namens unterscheidet – was lediglich bedeutet, dass Sie Ihren lokalen Geltungsbereich nicht wahrnehmen, keines der Objekte des Anrufers. So können Sie die Einheimischen des Anrufers nicht mutieren (deshalb ist es nicht pass-by-Referenz).

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

Python hat das Konzept der veränderlichen und unveränderlichen Gegenstände . Ein Objekt wie ein String oder eine Ganzzahl ist unveränderlich – jede Änderung, die Sie machen, erzeugt einen neuen String oder eine ganze Zahl.

Listen sind veränderlich und können manipuliert werden. Siehe unten.

 a = [1, 2, 3] b = [1, 2, 3] c = a print a is b, a is c # False True print a, b, c # [1, 2, 3] [1, 2, 3] [1, 2, 3] a.reverse() print a, b, c # [3, 2, 1] [1, 2, 3] [3, 2, 1] print a is b, a is c # False True 

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

Es wird ausdrücklich in der Dokumentation erwähnt. Die .sort() Funktion mutiert die Sammlung. 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.

 a = 1 b = a a = 2 print b 

Referenzen sind nicht die gleichen wie separate Objekte.

.sort() mutiert auch die Sammlung.

  • Pythonumfang [doppelte]
  • Wie kann man Variablen eines anderen Bereichs ändern?
  • UnboundLocalError bei der Manipulation von Variablen ergibt inkonsistentes Verhalten
  • Python: Wie erfasse ich eine Variable, die in einem nicht globalen Ahnenumfang angegeben ist?
  • String mit 'f' Präfix in python-3.6
  • Wie kann ich auf eine Klassenvariable in einem Initialisierer in Python zugreifen?
  • Wie kann man neue Scopes in Python schaffen?
  • Warum ist eine Klassenvariable nicht im Listenverständnis definiert, sondern eine andere ist?
  • Kurze Beschreibung der Scoping Regeln?
  • Mit einer Variablen in einem Versuch, Fang, endgültige Aussage, ohne es draußen zu erklären
  • Python: Wie kann ich eval () im lokalen Gültigkeitsbereich einer Funktion ausführen?
  • Python ist die beste Programmiersprache der Welt.