Une explication des objets mutables et des objets immuables en Python

零下一度
Libérer: 2017-07-09 11:56:23
original
1853 Les gens l'ont consulté

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
Copier après la connexion

Regardons la chaîne


astr = 'good'
bstr = 'good'
cstr = astr + ''
print(cstr is bstr) # True
print(id(astr), id(bstr), id('good')) # 三个id相同
Copier après la connexion

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和上面的不一样
Copier après la connexion

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)
Copier après la connexion

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)没有变
Copier après la connexion

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,类型都不同
Copier après la connexion

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都不同
Copier après la connexion

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也一样
Copier après la connexion

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)) # 相等
Copier après la connexion

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的改变而改变
Copier après la connexion

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]没有变化
Copier après la connexion

comme paramètre de fonction

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) # 没有变
Copier après la connexion

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]没有变
Copier après la connexion

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)
Copier après la connexion

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal