Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erklärung veränderlicher Objekte und unveränderlicher Objekte in Python

Detaillierte Erklärung veränderlicher Objekte und unveränderlicher Objekte in Python

零下一度
零下一度Original
2017-06-30 14:30:401868Durchsuche

Veränderliche Objekte und unveränderliche Objekte in Python

Was sind veränderliche/unveränderliche Objekte?

  • Unveränderliche Objekte, auf die Objekte verweisen Der Wert im Speicher kann nicht sein geändert. Wenn eine Variable geändert wird, entspricht dies dem Kopieren und anschließenden Ändern des ursprünglichen Werts, da der Wert, auf den sie sich bezieht, nicht geändert werden kann. Dadurch wird eine neue Adresse geöffnet, und die Variable zeigt auf diese neue Adresse.

  • Veränderbares Objekt, der Wert im Speicher, auf den das Objekt zeigt, kann geändert werden. Nachdem eine Variable (genauer gesagt eine Referenz) geändert wurde, wird der Wert, auf den sie sich bezieht, tatsächlich direkt geändert. Es gibt kein Kopierverhalten und es wird keine neue ausgehende Adresse geöffnet . .

In Python sind der numerische Typ

( und int), die Zeichenfolge str und das Tupel-Tupel allesamt unveränderliche Typen. Listen, Wörterbücher und Mengen sind Variablentypen. float

Es ist intuitiver, den Code zu betrachten. Schauen wir uns zunächst Beispiele für unveränderliche Objekte an

Unveränderliche Objekte

Lassen Sie mich zunächst eines erklären: dient dazu, festzustellen, ob die IDs zweier Objekte gleich sind, während is bestimmt den Inhalt. ==

a = 2b = 2c = a + 0 c += 0print(id(a), id(b), id(2))  # id都相同print(c is b) #True
Schauen wir uns die Zeichenfolge

astr = 'good'bstr = 'good'cstr = astr + ''print(cstr is bstr) # Trueprint(id(astr), id(bstr), id('good'))  # 三个id相同
an, die das gleiche Ergebnis wie der numerische Typ hat. Wenn die folgende Situation vorliegt, ist die Variable nach der Änderung nicht mehr

good

astr = 'good'print(id(astr))
astr += 'aa'print(id(astr)) # id和上面的不一样

Da es sich um ein unveränderliches Objekt handelt, entspricht der Wert dem Speicher Die Variable darf nicht geändert werden. Wenn eine Variable geändert werden soll, wird der ursprüngliche Wert tatsächlich kopiert und dann geändert, eine neue Adresse wird geöffnet und Astr zeigt auf diese neue Adresse (daher ist die ID des vorherigen und des vorherigen Astr unterschiedlich). Der ursprüngliche Astr ist anders, denn wenn ein anderes Objekt darauf zeigt, wird es durch Müll gesammelt. Dies gilt auch für die Typen int und float.

Sehen Sie sich das Tupel an

add = (1, 2, 3)
aee = (1, 2, 3)print(id(add), id(aee), id((1, 2, 3)))  # id各不相同aee = (1, 2, 3)print(id(aee))
aee += () # 加空元组print(id(aee))  # id变了!print(aee)  #(1 ,2,3)
Obwohl es so aussieht,

sollte es mit dem oben Gesagten übereinstimmen. Ist das ein veränderliches Objekt? Schauen Sie noch einmal (1 ,2, 3)

add = (1, 2, 3)
aee = add 
print(id(aee), id(add)) # 这两个id一样aee += (4, 5, 6)print(id(aee)) # aee的id变了!print(add) # add还是(1, 2, 3)没有变
stimmt mit dem numerischen Typ und dem str-Typ überein. Wenn es sich um ein veränderliches Objekt

handelt, ist es sicher, dass sie auf dieselbe Adresse (dieselbe ID) verweisen. Dabei handelt es sich jedoch nicht um unterschiedliche Verweise auf dasselbe Objekt, denn wenn dies der Fall ist, führen Änderungen in aee zu Änderungen in add, was in tuple nicht der Fall ist. Tuple ist also ein unveränderliches Objekt, unterscheidet sich jedoch geringfügig von den Typen str und numeric. Die Unveränderlichkeit von Tupeln bedeutet normalerweise, dass die in ihnen gespeicherten Werte nicht geändert werden können (add = aeeIn einigen Sonderfällen, z. B. bei einer in einem Tupel gespeicherten Liste, können die Elemente in der Liste geändert werden. Aber tatsächlich ist das Tupel wurde nicht geändert).

Für

sind ihre IDs gleich, solange sie denselben Typ und denselben Wert haben. (Warum sagen Sie, dass sie vom gleichen Typ sind?) str、int、float

a = 2.0b = 2print(a is b)  # False, 一个int一个float,类型都不同
2 und 2.0 befinden sich nicht an derselben Adresse.

Beispiele für veränderliche Objekte

lis = [1, 2, 3]
lis2 = [1, 2, 3]# 虽然它们的内容一样,但是它们指向的是不同的内存地址print(lis is lis2)print(id(lis), id(lis2), id([1, 2, 3]))  # 三个id都不同
Aufgabe anschauen

alist = [1, 2, 3]# alist实际上是对对象的引用,blist = alist即引用的传递,现在两个引用都指向了同一个对象(地址)blist = alistprint(id(alist), id(blist))  # id一样# 所以其中一个变化,会影响到另外一个blist.append(4)print(alist)  # 改变blist, alist也变成了[1 ,2 ,3 4]print(id(alist), id(blist))  # id一样,和上面值没有改变时候的id也一样

Dieser Satz. blist = alist ist eigentlich eine Referenz auf das Objekt, alist ist die Übertragung der Referenz, und jetzt verweisen beide Referenzen auf dasselbe Objekt (Adresse). Änderungen in einem wirken sich also auf das andere aus. blist = alist

Sehen Sie sich set an

abb = {1, 2, 3}
acc = abbprint(id(abb), id(acc))
acc.add(4)print(abb)  # {1, 2, 3, 4} print(id(abb), id(acc)) # 相等
was mit dem Beispiel der obigen Liste übereinstimmt.

Da das gezeigte Objekt eines variablen Objekts geändert werden kann, muss keine Kopie erstellt und dann geändert werden. Es kann direkt an Ort und Stelle geändert werden, sodass kein neuer Speicher geöffnet wird, und die ID bleibt vor und nach der Änderung unverändert.

Natürlich ist dies bei unveränderlichen Objekten nicht der Fall. Sie können es damit vergleichen

abc = 3dd = abc
dd = 43print(abc)  # 3,并不随dd的改变而改变
Aber wenn es eine Kopie ist, handelt es sich nur um eine Kopie den Inhalt und die Weitergabe und nicht Zitierung.

Dies ist besonders nützlich, wenn Sie die Werte einer Liste verwenden möchten, ohne die ursprüngliche Liste zu ändern.

blist = alist[:]  # or alist.copy()print(alist is blist)  # Falseblist.append(4)print(alist)  # 还是[1,2 ,3]没有变化
als Funktionsparameter

Als Funktionsparameter ist es dasselbe, während unveränderliche Typen Inhalte übergeben.

test_list = [1, 2, 3, 4]
test_str = 'HAHA'def change(alist):
    alist.append(5)def not_change(astr):
    astr.lower()


change(test_list)
not_change(test_str)print(test_list)  # 改变了原来的值print(test_str)  # 没有变
Wenn Sie den Wert der ursprünglichen Liste nicht ändern möchten, können die Parameter natürlich in einer Kopie der Spaltenvariablen übergeben werden.

alsit[:]

Interessantes Beispiel

Wenn wir uns ein weiteres interessantes Beispiel ansehen, wissen wir, dass eine Liste mit

zu einer Liste hinzugefügt werden kann. +

a1 = [1, 2, 3]
a2 = a1print(id(a1), id(a2))# 实际上是a2指向了新的对象,id已经改变。# 所以现在a2、a1并不是同一对象的两个引用了,a2变化a1不会改变a2 = a2 + [4] # 这个等式中,右边的a2还是和a1的id一样的,一旦赋值成功,a2就指向新的对象print(id(1), id(a2))  # 不等,a2的id变化了print(a1) # [1, 2, 3]没有变
Wenn Sie so schreiben

a1 = [1, 2, 3]
a2 = a1print(id(a1), id(a2))
a2 += [4]  # 相当于调用了a2.extend([4]),原地改变并没有新的对象产生print(id(1), id(a2))  # 相等,a2的id没有变化print(a1)
Der Unterschied besteht darin, dass

dem Aufruf von a2 += [4]Es entspricht entspricht einem Ortswechsel und es werden keine neuen Objekte generiert. a2.extend([4])

Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung veränderlicher Objekte und unveränderlicher Objekte in 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