Pourquoi les cordes de python et les tuples sont-ils immuables?
Je ne sais pas pourquoi les cordes et les tuples ont été faits pour être immuables; quels sont les avantages et les désavantages de les rendre immuables?
6 réponses
L'un est la performance: savoir qu'un la chaîne est immuable, il est facile de étalez-la au moment de la construction - stockage fixe et immuable exigence. C'est également l'un des motifs de la distinction entre des tuples et des listes. Cela permet aussi à l' mise en œuvre pour réutiliser en toute sécurité chaîne objet. Par exemple, le Disponible mise en œuvre utilisations préaffectées objets pour chaînes à un caractère, et retourne l'original chaîne pour chaîne les opérations qui ne pas modifier le contenu.
l'autre est que les cordes en Python sont considérés comme "élémentaires" nombre. Pas de montant de de l'activité de la changez la valeur 8 pour n'importe quoi d'autre, et en Python, aucune activité va remplacer la chaîne "huit" pour quelque chose d'autre.
http://effbot.org/pyfaq/why-are-python-strings-immutable.htm
Imaginez un langage appelé FakeMutablePython, où vous pouvez modifier les chaînes en utilisant l'assignation de liste et tel que (comme mystr[0] = 'a'
)
a = "abc"
qui crée une entrée en mémoire dans l'adresse mémoire 0x1, contenant" abc", et l'identifiant a
pointant vers elle.
maintenant, dites-le..
b = a
crée l'identifiant b
et le pointe vers la même adresse mémoire de 0x1
maintenant, si la chaîne était mutable, et vous changez b
:
b[0] = 'z'
Cela modifie le premier octet de la chaîne stockée à 0x1 z
.. Puisque l'identifiant a
pointe ici vers, Ainsi cette chaîne serait modifiée aussi, donc..
print a
print b
..les deux produiraient zbc
cela pourrait donner lieu à un comportement vraiment bizarre et inattendu. Les clés de dictionnaire serait un bon exemple de ceci:
mykey = 'abc'
mydict = {
mykey: 123,
'zbc': 321
}
anotherstring = mykey
anotherstring[0] = 'z'
maintenant dans Fakemutable Python, les choses deviennent plutôt étranges - vous avez d'abord deux clés dans le dictionnaire, "abc" et "zbc".. Ensuite, vous modifiez la chaîne "abc" (via l'identifiant anotherstring
), "zbc", de sorte que le dict a deux clés, "zbc" et "zbc"...
une solution à cette bizarrerie serait, chaque fois que vous assignez une chaîne à un identifiant (ou l'utilisez comme une clé dict), qu'elle copie la chaîne de 0x1 à 0x2.
cela empêche le ci-dessus, mais que faire si vous avez une chaîne qui nécessite 200 Mo de mémoire?
a = "really, really long string [...]"
b = a
soudainement ton script prend 400 Mo de mémoire? Ce n'est pas très bon.
Qu'en est-il si nous le pointons vers la même adresse mémoire, jusqu'à ce que nous le modifions? Copy on write . Le problème est que cela peut être assez compliqué à faire..
C'est là que l'immutabilité.. Au lieu d'exiger la méthode .replace()
pour copier la chaîne de la mémoire dans une nouvelle adresse, puis la modifier et la retourner.. Nous rendons toutes les chaînes immuables, et donc la fonction doit créer une nouvelle chaîne pour retourner. Ceci explique le code suivant:
a = "abc"
b = a.replace("a", "z")
et est prouvé par:
>>> a = 'abc'
>>> b = a
>>> id(a) == id(b)
True
>>> b = b.replace("a", "z")
>>> id(a) == id(b)
False
(la fonction id()
renvoie l'adresse mémoire de l'objet)
Un gros avantage de les rendre immuable, c'est qu'ils peuvent être utilisés comme clés dans un dictionnaire. Je suis sûr que les structures de données internes utilisées par les dictionnaires seraient assez perturbées si les clés étaient autorisées à changer.
les types immuables sont conceptuellement beaucoup plus simples que les types mutables. Par exemple, vous n'avez pas besoin de jouer avec les constructeurs de copie ou avec la const-rectitude comme dans C++. Plus les types sont immuables, plus la langue devient facile. Ainsi les langues les plus faciles sont les langues purement fonctionnelles sans aucun état global (parce que le calcul lambda est beaucoup plus facile que les machines de Turing, et tout aussi puissant), bien que beaucoup de gens ne semblent pas apprécier cela.
Perl a des cordes mutables et semble fonctionner très bien. Ce qui précède semble être beaucoup de main agitant et de rationalisation pour une décision de conception arbitraire.
ma réponse à la question de savoir pourquoi Python a des cordes immuables, parce que le créateur de Python Guido van Rossum l'a voulu ainsi et il a maintenant des légions de fans qui vont défendre cette décision arbitraire à leur dernier souffle.
on pourrait se demander pourquoi Perl n'a pas des cordes immuables et tout un tas de gens écriraient à quel point le concept même de cordes immuables est horrible et pourquoi C'est la meilleure idée jamais (TM) que Perl n'en ait pas.
pros: Performance
cons: vous ne pouvez pas changer les mutables.