Je ne sais pas pourquoi les chaînes et les tuples ont été conçus pour être immuables ; quels sont les avantages et les inconvénients de les rendre immuables ?
La meilleure explication que j'ai entendue !
Je ne sais pas pourquoi les chaînes et les tuples ont été conçus pour être immuables ; quels sont les avantages et les inconvénients de les rendre immuables ?
Imaginez un langage appelé FakeMutablePython, dans lequel vous pouvez modifier des chaînes de caractères à l'aide d'assignations de listes et autres (par exemple mystr[0] = 'a'
)
a = "abc"
Cela crée une entrée en mémoire à l'adresse 0x1, contenant "abc", et l'identifiant a
en la pointant du doigt.
Maintenant, disons que vous faites..
b = a
Cela crée l'identifiant b
et le dirige également vers la même adresse mémoire de 0x1
Maintenant, si la chaîne est mutable, et que vous changez b
:
b[0] = 'z'
Cela modifie le premier octet de la chaîne stockée à 0x1 en z
.. Puisque l'identifiant a
pointe vers ici à, donc cette chaîne serait altérée aussi, donc
print a
print b
donneraient tous deux des résultats zbc
Cela pourrait donner lieu à des comportements vraiment étranges et inattendus. Les clés de dictionnaire en sont un bon exemple :
mykey = 'abc'
mydict = {
mykey: 123,
'zbc': 321
}
anotherstring = mykey
anotherstring[0] = 'z'
Maintenant, dans FakeMutablePython, les choses deviennent plutôt étranges - vous avez initialement deux clés dans le dictionnaire, "abc" et "zbc" . Ensuite, vous modifiez la chaîne "abc" (via l'identifiant anotherstring
) à "zbc", donc 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 que vous l'utilisez comme clé de dict), de copier la chaîne de 0x1 à 0x2.
Cela permet d'éviter ce qui précède, 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, votre script prend 400MB de mémoire ? Ce n'est pas très bon.
Et si nous le faisons pointer vers la même adresse mémoire, jusqu'à ce que nous le modifions ? Copie sur l'écriture . Le problème est que cela peut être assez compliqué à faire
C'est là que l'immuabilité entre en jeu Au lieu d'exiger que le .replace()
pour copier la chaîne de la mémoire dans une nouvelle adresse, puis la modifier et la renvoyer . Nous venons de rendre toutes les chaînes immuables, et donc la fonction doit créer une nouvelle chaîne à 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
(le id()
renvoie l'adresse mémoire de l'objet)
@Dineshkumar Non, je suis assez sûr. "abc"
et "abcd"
sont des objets différents, sans aucun rapport entre eux. stackoverflow.com/questions/5722006/
L'une d'elles est la performance : savoir qu'une chaîne est immuable, il est facile de la l'étaler au moment de la construction. de stockage fixes et immuables. fixes et immuables. C'est également l'une des raisons de la distinction entre les tuples et les listes. Cela permet également à la l'implémentation de réutiliser en toute sécurité les en toute sécurité. Par exemple, l'implémentation CPython utilise des objets préalloués pré-alloués pour les chaînes à un seul caractère, et renvoie généralement la chaîne originale originale pour les opérations sur les chaînes qui ne modifie pas le contenu.
L'autre est que les chaînes de caractères en Python sont considérées comme aussi "élémentaires" que les nombres. Aucune activité ne pourra changer la valeur 8 en quelque chose d'autre, et en Python, aucune activité ne changera la chaîne "huit" en en autre chose.
Le lien vers effbot est mort, peut-être le remplacer par un lien vers les archives internet ? web.archive.org/web/20201031092707/http://effbot.org/pyfaq/
Mais vous pouvez utiliser n'importe quelle instance d'objet créée par l'utilisateur, qui est évidemment mutable. La "clé" n'est donc probablement que l'adresse mémoire, et si les chaînes de caractères étaient mutables, vous pourriez toujours utiliser leur adresse mémoire unique.
@Triptych ce qui ne serait pas ce que l'on veut pour les chaînes de caractères -- on voudrait qu'elles soient clé par valeur, sinon les dictionnaires seraient de peu ou pas d'utilité.....
@Hejazzman ce n'est pas comme ça que les dicts python fonctionnent. La valeur littérale de la chaîne n'est pas utilisée comme clé du dict, mais un hash de la chaîne est utilisé. Prouvez-le vous-même avec 'abc'.__hash__()
.
Les types immuables sont conceptuellement beaucoup plus simples que les types mutables. Par exemple, il n'est pas nécessaire de s'embarrasser de constructeurs de copie ou de const-correctness comme en C++. Plus les types sont immuables, plus le langage est simple. Ainsi, les langages les plus simples sont les langages fonctionnels purs sans état global (parce que le lambda calculus est beaucoup plus simple que les machines de Turing, et tout aussi puissant), bien que beaucoup de gens ne semblent pas apprécier cela.
Perl a des chaînes de caractères mutables et semble fonctionner parfaitement. Ce qui précède ressemble à beaucoup d'agitation et de rationalisation pour une décision de conception arbitraire.
Ma réponse à la question de savoir pourquoi Python a des chaînes immuables, c'est parce que le créateur de Python, Guido van Rossum, le voulait ainsi et qu'il a maintenant des légions de fans qui défendront cette décision arbitraire jusqu'à leur dernier souffle.
Vous pourriez poser une question similaire, à savoir pourquoi Perl n'a pas de chaînes immuables, et toute une série de personnes écriraient à quel point le concept même de chaînes immuables est horrible et pourquoi c'est la meilleure idée du monde (TM) que Perl n'en ait pas.
Perl n'a pas vraiment de chaînes de caractères : il a des scalaires, qui peuvent se comporter comme des chaînes de caractères ou des nombres (plus d'un type de ces derniers). Si les scalaires étaient immuables, cela deviendrait du Perl purement fonctionnel et les développeurs Perl du monde entier se suicideraient en s'attribuant undef.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
1 votes
En dehors de l'implémentation interne de l'interpréteur python, cette conception a-t-elle un sens pour l'écriture de programmes ? (par exemple, serait-il plus facile si les tuples et les chaînes de caractères étaient mutables ?) si c'est le cas, quels seraient les exemples de choix de tuples immuables par rapport aux listes ? (ou peut-être, des chaînes de caractères mutables contre des chaînes de caractères python)
3 votes
Il existe un style entier de programmation appelé programmation fonctionnelle, où tout est immuable. fr.wikipedia.org/wiki/Functional_programming
2 votes
Python FAIT ont des chaînes de caractères et des tuples mutables ; ils s'écrivent
bytearray
etlist
respectivement.