Sind nicht Python-Streicher unveränderlich?

Mein Verständnis war, dass Python-Strings unveränderlich sind.

Ich habe den folgenden Code ausprobiert:

a = "Dog" b = "eats" c = "treats" print a, b, c # Dog eats treats print a + " " + b + " " + c # Dog eats treats print a # Dog a = a + " " + b + " " + c print a # Dog eats treats # !!! 

Sollte Python die Aufgabe nicht verhindern? Ich vermisse vermutlich etwas.

Irgendeine Idee?

15 Solutions collect form web for “Sind nicht Python-Streicher unveränderlich?”

Zuerst zeigte man auf die Saite "Hund". Dann haben Sie die Variable a geändert, um auf einen neuen String "Dog isst Leckereien" zu zeigen. Sie haben die Saite "Hund" nicht wirklich mutiert. Strings sind unveränderlich, Variablen können auf alles hinweisen, was sie wollen.

Die Streichobjekte selbst sind unveränderlich.

Die Variable, a , die auf die Zeichenfolge zeigt, ist veränderlich.

Erwägen:

 a = "Foo" # a now points to "Foo" b = a # b points to the same "Foo" that a points to a = a + a # a points to the new string "FooFoo", but b still points to the old "Foo" print a print b # Outputs: # FooFoo # Foo # Observe that b hasn't changed, even though a has. 

Die Variable a zeigt auf das Objekt "Hund". Es ist am besten, an die Variable in Python als Tag zu denken. Du kannst den Tag zu verschiedenen Objekten verschieben, was du getan hast, als du a = "dog" zu a = "dog eats treats" verändert hast.

Allerdings bezieht sich die Unveränderlichkeit auf das Objekt, nicht auf das Tag.


Wenn du a[1] = 'z' versucht hast, um "dog" in "dzg" , würdest du den Fehler bekommen:

 TypeError: 'str' object does not support item assignment" 

Weil Strings keine Itemzuordnung unterstützen, also sind sie unveränderlich.

Eine Variable ist nur ein Label, das auf ein Objekt zeigt. Das Objekt ist unveränderlich, aber man kann das Etikett auf ein ganz anderes Objekt stellen, wenn man will.

Etwas ist nur dann veränderlich, wenn wir die im Speicherplatz gehaltenen Werte ändern können, ohne den Speicherplatz selbst zu ändern.

Der Trick ist: Wenn Sie feststellen, dass der Speicherplatz vor und nach der Änderung gleich ist, ist es veränderlich.

Zum Beispiel ist die Liste veränderlich. Wie?

 >> a = ['hello'] >> id(a) 139767295067632 # Now let's modify #1 >> a[0] = "hello new" >> a ['hello new'] Now that we have changed "a", let's see the location of a >> id(a) 139767295067632 so it is the same as before. So we mutated a. So list is mutable. 

Ein String ist unveränderlich. Wie beweisen wir das?

 > a = "hello" > a[0] 'h' # Now let's modify it > a[0] = 'n' ---------------------------------------------------------------------- 

wir bekommen

TypeError: 'str' Objekt unterstützt keine Positionszuordnung

Also haben wir es versäumt, die Saite zu mutieren. Es bedeutet, dass eine Saite unveränderlich ist.

Bei der Neuzuordnung ändern Sie die Variable, um auf eine neue Position zu zeigen. Hier haben Sie die Saite nicht mutiert, sondern die Variable selbst mutiert. Das Folgende ist, was du tust.

 >> a = "hello" >> id(a) 139767308749440 >> a ="world" >> id(a) 139767293625808 

id vor und nach der reassignment ist anders, so dass dies beweist, dass Sie eigentlich nicht mutieren, sondern zeigt die Variable auf neue Position. Das ist nicht mutiert diese Zeichenfolge, sondern mutiert diese Variable.

 l = [1,2,3] print id(l) l.append(4) print id(l) #object l is the same a = "dog" print id(a) a = "cat" print id(a) #object a is a new object, previous one is deleted 

Es gibt einen Unterschied zwischen Daten und dem Label, dem es zugeordnet ist. Zum Beispiel, wenn Sie tun

 a = "dog" 

Die Daten "dog" entsteht und unter das Label a . Das Etikett kann sich ändern, aber was ist im Speicher nicht. Die Daten "dog" wird noch im Gedächtnis existieren (bis der Müllsammler es löscht), nachdem du es getan hast

 a = "cat" 

In deinem Programm a jetzt ^ zeigt auf "cat" aber die Schnur "dog" hat sich nicht geändert.

Die Aussage a = a + " " + b + " " + c kann auf der Grundlage von Zeigern abgebaut werden.

a + " " sagt mir, was a Hinweis auf, die nicht geändert werden können, und fügen Sie " " zu meinem aktuellen Arbeitssatz.

Erinnerung:

 working_set = "Dog " a = "Dog" b = "eats" c = "treats" 

+ b sagt mir, was b zeigt, was nicht geändert werden kann, und füge es dem aktuellen Arbeitssatz hinzu.

Erinnerung:

 working_set = "Dog eats" a = "Dog" b = "eats" c = "treats" 

+ " " + c sagt fügen Sie " " zum aktuellen Satz hinzu. Dann gib mir, was c zeigt, was nicht geändert werden kann, und füge es dem aktuellen Arbeitssatz hinzu. Erinnerung:

 working_set = "Dog eats treats" a = "Dog" b = "eats" c = "treats" 

Schließlich, a = sagt, setzen Sie meinen Zeiger auf den resultierenden Satz zu zeigen.

Erinnerung:

 a = "Dog eats treats" b = "eats" c = "treats" 

"Dog" wird zurückgefordert, weil sich keine Zeiger mehr mit dem Gedächtnis verbinden. Wir haben niemals den Gedächtnisabschnitt "Dog" gewechselt, der in unveränderlichem Zustand ist. Allerdings können wir ändern, welche Etiketten, wenn überhaupt, auf diesen Abschnitt des Gedächtnisses zeigen.

Python-Strings sind unveränderlich. Allerdings ist a kein String: Es ist eine Variable mit einem String-Wert. Sie können die Zeichenfolge nicht mutieren, sondern können den Wert der Variablen in eine neue Zeichenfolge ändern.

>>> a = 'dogs'

>>> a.replace('dogs', 'dogs eat treats')

'dogs eat treats'

>>> print a

'dogs'

Unveränderlich, nicht wahr ?!

Der Variablenwechselteil wurde bereits diskutiert.

Erwägen:

 >>> a='asdf' >>> a.__repr__ <method-wrapper '__repr__' of str object at 0x1091aab90> >>> a='asdf' >>> a.__repr__ <method-wrapper '__repr__' of str object at 0x1091aab90> >>> a='qwer' >>> a.__repr__ <method-wrapper '__repr__' of str object at 0x109198490> 

Beachten Sie, dass sich der Hex-Speicherplatz nicht geändert hat, als ich denselben Wert in der Variable zweimal gespeichert habe. Es hat sich geändert, wenn ich einen anderen Wert speichere. Die Saite ist unveränderlich. Nicht wegen der Eifersucht, sondern weil Sie die Leistungsstrafe bezahlen, um ein neues Objekt im Gedächtnis zu schaffen. Die Variable a ist nur ein Label und die Speicheradresse. Es kann geändert werden, um etwas zu zeigen.

Variablen können auf irgendwo hinweisen, was sie wollen. Ein Fehler wird ausgelöst, wenn Sie Folgendes tun:

 a = "dog" print a #dog a[1] = "g" #ERROR!!!!!! STRINGS ARE IMMUTABLE 

Zusammenfassend:

 a = 3 b = a a = 3+2 print b # 5 

Nicht unveränderlich:

 a = 'OOP' b = a a = 'p'+a print b # OOP 

Unveränderlich:

 a = [1,2,3] b = range(len(a)) for i in range(len(a)): b[i] = a[i]+1 

Dies ist ein Fehler in Python 3, weil es unveränderlich ist. Und kein Fehler in Python 2, weil es eindeutig nicht unveränderlich ist.

Betrachten Sie diese Ergänzung zu Ihrem Beispiel

  a = "Dog" b = "eats" c = "treats" print (a,b,c) #Dog eats treats d = a + " " + b + " " + c print (a) #Dog print (d) #Dog eats treats 

Eine der genaueren Erklärungen, die ich in einem Blog gefunden habe, ist:

In Python ist (fast) alles ein Gegenstand. Was wir gemeinhin als "Variablen" in Python bezeichnen, werden eher namentlich genannt. Ebenso ist "Zuordnung" wirklich die Bindung eines Namens an ein Objekt. Jede Bindung hat einen Bereich, der seine Sichtbarkeit definiert, in der Regel den Block, in dem der Name stammt.

Z.B:

 some_guy = 'Fred' # ... some_guy = 'George' 

Wenn wir später sagen, some_guy = 'George', ist das String-Objekt mit 'Fred' unberührt. Wir haben gerade die Bindung des Namens some_guy geändert. Wir haben jedoch nicht die "Fred" oder "George" String Objekte geändert. Soweit es uns betrifft, können sie auf unbestimmte Zeit leben.

Link zum Blog: https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/

Sie können ein numpy Array unveränderlich machen und das erste Element verwenden:

 numpyarrayname[0] = "write once" 

dann:

 numpyarrayname.setflags(write=False) 

oder

 numpyarrayname.flags.writeable = False 
Python ist die beste Programmiersprache der Welt.