Maison > Article > développement back-end > Une explication des objets mutables et des objets immuables en Python
L'éditeur suivant vous proposera une brève discussion sur les objets mutables et les objets immuables en Python. L'éditeur pense que c'est plutôt bien, alors je vais le partager avec vous maintenant et le donner comme référence. Suivons l'éditeur et jetons un coup d'oeil
Qu'est-ce qu'un objet mutable/immuable
Objet immuable, la mémoire pointée par l'objet Le la valeur dans ne peut pas être modifiée. Lors de la modification d'une variable , puisque la valeur à laquelle elle fait référence ne peut pas être modifiée, cela équivaut à copier la valeur d'origine puis à la modifier. Cela ouvrira une nouvelle adresse et la variable pointera vers cette nouvelle. . adresse.
Objet mutable, la valeur dans la mémoire pointée par l'objet peut être modifiée. Une fois la variable (pour être précis, fait référence à ) est modifiée, la valeur à laquelle elle fait référence est en fait modifiée directement. Aucun comportement de copie ne se produit et aucune nouvelle adresse sortante n'est ouverte. En termes simples, elle est modifiée. en place.
En Python, le type numérique (int et float), la stringstr et le tuple tuple sont tous des types immuables. Les listes, dictionnaires et ensembles sont des types de variables.
Il est plus intuitif de regarder le code. Regardons d'abord les exemples d'objets immuables
Objets immuables
Expliquez d'abord une chose : il s'agit de déterminer si les identifiants de deux objets sont les mêmes, et = = Le jugement est de savoir si le contenu est le même.
a = 2 b = 2 c = a + 0 c += 0 print(id(a), id(b), id(2)) # id都相同 print(c is b) #True
Regardons la chaîne
astr = 'good' bstr = 'good' cstr = astr + '' print(cstr is bstr) # True print(id(astr), id(bstr), id('good')) # 三个id相同
qui a le même résultat que le type numérique . Si la situation suivante se produit, la variable n'est plus bonne
astr = 'good' print(id(astr)) astr += 'aa' print(id(astr)) # id和上面的不一样
après modification Puisqu'il s'agit d'un objet immuable, la valeur de la mémoire correspondant à la variable est. ne peut pas être modifié. Lorsqu'une variable doit être modifiée, la valeur d'origine est effectivement copiée puis modifiée, une nouvelle adresse est ouverte et astr pointe vers cette nouvelle adresse (donc l'identifiant de l'astr précédent et de l'astr précédent est différent de la valeur correspondante). l'astr d'origine est différent car si un autre objet pointe vers lui, il sera récupéré. C'est la même chose pour les types int et float.
Regardez le tuple
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)
Bien qu'il semble qu'ils le soient tous (1,2, 3), cela devrait être cohérent avec ce qui précède . Est-ce un objet mutable ? Regardez à nouveau
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)没有变
est cohérent avec le type numérique et le type str. S'il s'agit d'un objet variable add = aee, il est certain qu'ils pointent vers la même adresse (même id). Mais il ne s’agit pas de références différentes au même objet, car si c’est le cas, les changements dans aee entraîneront des changements dans add, ce qui n’est pas le cas dans tuple. Le tuple est donc un objet immuable, mais il est légèrement différent des types str et numériques. L'immuabilité des tuples signifie généralement que les valeurs qui y sont stockées ne peuvent pas être modifiées (dans certains cas particuliers, comme une liste stockée dans un tuple, les éléments de la liste peuvent être modifiés. Mais en fait, le tuple n'a pas été modifié).
Pour str, int et float, tant qu'ils ont le même type et la même valeur, leurs identifiants seront les mêmes. (Pourquoi dites-vous qu'ils sont du même type ?)
a = 2.0 b = 2 print(a is b) # False, 一个int一个float,类型都不同
2 et 2.0 ne sont pas à la même adresse.
Exemples d'objets mutables
lis = [1, 2, 3] lis2 = [1, 2, 3] # 虽然它们的内容一样,但是它们指向的是不同的内存地址 print(lis is lis2) print(id(lis), id(lis2), id([1, 2, 3])) # 三个id都不同
Regardez la mission
alist = [1, 2, 3] # alist实际上是对对象的引用,blist = alist即引用的传递,现在两个引用都指向了同一个对象(地址) blist = alist print(id(alist), id(blist)) # id一样 # 所以其中一个变化,会影响到另外一个 blist.append(4) print(alist) # 改变blist, alist也变成了[1 ,2 ,3 4] print(id(alist), id(blist)) # id一样,和上面值没有改变时候的id也一样
blist = alist. alist est en fait une référence à l'objet, blist = alist est le transfert de la référence, et maintenant les deux références pointent vers le même objet (adresse). Donc un changement affectera l'autre
et regardez l'ensemble
abb = {1, 2, 3} acc = abb print(id(abb), id(acc)) acc.add(4) print(abb) # {1, 2, 3, 4} print(id(abb), id(acc)) # 相等
qui est cohérent avec l'exemple de la liste ci-dessus.
Puisque l'objet pointé d'un objet variable peut être modifié, il n'est pas nécessaire d'en faire une copie puis de le modifier. Il peut être modifié directement sur place, donc aucune nouvelle mémoire ne sera ouverte, ni l'identifiant. reste inchangé avant et après le changement.
Bien sûr, ce n'est pas le cas pour les objets immuables. Vous pouvez le comparer avec ceci
abc = 3 dd = abc dd = 43 print(abc) # 3,并不随dd的改变而改变
Mais si c'est une copie, c'est une copie. consiste simplement à copier le contenu, ce qui est transmis n'est pas cité. Ceci est particulièrement utile lorsque l'on souhaite utiliser les valeurs d'une liste sans modifier la liste d'origine.
blist = alist[:] # or alist.copy() print(alist is blist) # False blist.append(4) print(alist) # 还是[1,2 ,3]没有变化
comme paramètre de fonction, la même chose, variable type Ce qui est transmis est une référence et les types immuables reçoivent du contenu.
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) # 没有变
Bien sûr, si vous ne souhaitez pas modifier la valeur de la liste d'origine, les paramètres peuvent être transmis dans une copie de la variable de colonne. alsit[:]
Exemple intéressant
En regardant un autre exemple intéressant, nous savons que cette liste peut être ajoutée à une liste en utilisant +.
a1 = [1, 2, 3] a2 = a1 print(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]没有变
Si c'est écrit comme ça
a1 = [1, 2, 3] a2 = a1 print(id(a1), id(a2)) a2 += [4] # 相当于调用了a2.extend([4]),原地改变并没有新的对象产生 print(id(1), id(a2)) # 相等,a2的id没有变化 print(a1)
La différence est a2 += [4 ] , cette phrase équivaut à appeler a2.extend([4]), ce qui équivaut à changer de place, et aucun nouvel objet n'est généré.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!