Sind die Python-Ausdrücke i += x äquivalent zu i = i + x? Wenn Ihre Antwort „Ja“ ist, dann herzlichen Glückwunsch, Sie haben zu 50 % Recht. Warum sagen Sie, dass es nur zur Hälfte richtig ist? Nach unserem allgemeinen Verständnis gibt es keine Ähnlichkeiten oder Unterschiede zwischen den beiden, wenn es um Ganzzahloperationen geht. Gilt dies jedoch auch für Listenoperationen? Schauen Sie sich zunächst die folgenden zwei Codeteile an:
Code 1
>>> l1 = range(3) >>> l2 = l1 >>> l2 += [3] >>> l1 [0, 1, 2, 3] >>> l2 [0, 1, 2, 3]
Code 2
>>> l1 = range(3) >>> l2 = l1 >>> l2 = l2 + [3] >>> l1 [0, 1, 2] >>> l2 [0, 1, 2, 3]
Der Wert von l2 in Code 1 und Code 2 ist der gleich, aber Die Werte von l1 sind unterschiedlich, was bedeutet, dass i + = x und i = i + x nicht gleichwertig sind. Unter welchen Umständen sind sie also gleichwertig und unter welchen Umständen nicht?
Bevor Sie dieses Problem klären, müssen Sie zunächst zwei Konzepte verstehen: veränderliche Objekte und unveränderliche Objekte.
Es gibt drei gemeinsame Attribute, die jedes Objekt in Python hat: eindeutiger Bezeichner, Typ und Wert.
Eindeutige Identifikation: Wird verwendet, um die Einzigartigkeit eines Objekts im Speicher zu identifizieren. Sie ändert sich nicht, nachdem das Objekt erstellt wurde. Die Funktion id() kann die eindeutige Identifikation des Objekts anzeigen Typ: Bestimmt Die vom Objekt unterstützten Operationen sind unterschiedlich. Beispielsweise können Listen ein Längenattribut haben, Ganzzahlen jedoch nicht. Ebenso ändert sich der Typ eines Objekts nicht, sobald er bestimmt ist. Die Funktion type() kann die Typinformationen des Objekts zurückgeben.
Der Wert eines Objekts unterscheidet sich von einem eindeutigen Bezeichner. Die Werte einiger Objekte können durch bestimmte Operationen geändert werden veränderliche Objekte. (veränderlich), Objekte, deren Werte nicht geändert werden können, werden unveränderliche Objekte (unveränderlich) genannt
Unveränderliche Objekte (unveränderlich)
Bei unveränderlichen Objekten ist der Wert immer der Wert, wenn Es wurde zuerst erstellt. Jede Operation an diesem Objekt führt zur Erstellung eines neuen Objekts.
Die Ganzzahl „1“ ist ein unveränderliches Objekt. Bei der ersten Zuweisung zeigt a auf das Ganzzahlobjekt 1, aber nach der Ausführung der +=-Operation für die Variable a zeigt a auf ein anderes Ganzzahlobjekt 2 . Objekt 1 ist jedoch unverändert vorhanden und Variable a zeigt bereits auf ein neues Objekt 2. Zu den gängigen unveränderlichen Objekten gehören: int, tuple, set, str.>>> a = 1 >>> id(a) 32574568 >>> a += 1 >>> id(a) 32574544
Veränderliches Objekt (veränderlich)
Der Wert eines veränderlichen Objekts kann durch bestimmte Vorgänge dynamisch geändert werden, z. B. ein Listenobjekt, das kontinuierlich geändert werden kann Durch die Append-Methode werden Elemente kontinuierlich zur Liste hinzugefügt, und der Wert der Liste ändert sich ständig. Wenn ein Variablenobjekt zwei Variablen zugewiesen wird, teilen sie sich dasselbe Instanzobjekt und zeigen auf dieselbe Speicheradresse eine der Variablen, und es wirkt sich auch auf eine andere Variable aus.
>>> x = range(3) >>> y = x >>> id(x) 139726103041232 >>> id(y) 139726103041232 >>> x.append(3) >>> x [0, 1, 2, 3] >>> y [0, 1, 2, 3] >>> id(x) 139726103041232 >>> id(y) 139726103041232
+= Die Operation versucht zunächst, die __iadd__-Methode des Objekts aufzurufen. Wenn es keine solche Methode gibt, versuchen wir, die __add__-Methode aufzurufen Schauen Sie sich zunächst diese beiden Methoden an. Was ist der Unterschied zwischen diesen beiden Methoden? Zwei Parameter ändern sich nicht.
__iadd__-Methode empfängt auch zwei Parameter, aber es handelt sich um eine direkte Operation, was bedeutet, dass sie den Wert des ersten Parameters ändert, da dies erfordert, dass das Objekt veränderbar ist, sodass keine Unveränderlichkeit erforderlich ist Objekte __iadd__-Methode.
Integer-Objekte verfügen offensichtlich nicht über die Methode __iadd__, während Listenobjekte die Methode __iadd__ bereitstellen.Die +=-Operation in Code 1 ruft die Methode __iadd__ auf, die den Wert des Objekts ändert, auf das l2 an Ort und Stelle zeigt
>>> hasattr(int, '__iadd__') False >>> hasattr(list, '__iadd__') True
>>> l2 += [3] # 代码1:使用__iadd__,l2的值原地修改
Die +-Operation in Code 2 ruft die Methode __add__ auf, die ein neues Objekt zurückgibt. Das ursprüngliche Objekt bleibt unverändert, l1 zeigt weiterhin auf das ursprüngliche Objekt und l2 zeigt bereits auf ein neues Objekt.
Das Obige ist der Unterschied zwischen den Ausdrücken i += x und i = i + x. Daher kann es beim Ausführen von +=-Operationen an Listen zu potenziellen Fehlern kommen, da sich l1 aufgrund von Änderungen in l2 ändert, genau wie die Parameter einer Funktion keine variablen Objekte als Schlüsselwortparameter verwenden sollten.