Bien que cette question n'ait aucune utilité réelle dans la pratique, je suis curieux de savoir comment Python effectue l'internement de chaînes. J'ai remarqué ce qui suit.
>>> "string" is "string"
True
C'est comme je m'y attendais.
Vous pouvez également le faire.
>>> "strin"+"g" is "string"
True
Et c'est assez intelligent!
Mais tu ne peux pas faire ça.
>>> s1 = "strin"
>>> s2 = "string"
>>> s1+"g" is s2
False
Pourquoi Python n'évaluerait-il pas, ne se rendrait-il pas s1+"g"
compte que c'est la même chose s2
et ne le ferait-il pas pointer vers la même adresse? Que se passe-t-il réellement dans ce dernier bloc pour qu'il revienne False
?
"string1" + "s2"
,10 + 3*20
, etc.) au moment de la compilation, mais les limites résultant des séquences à seulement 20 éléments (pour éviter[None] * 10**1000
de se dilater excessivement votre bytecode). C'est cette optimisation qui s'est effondrée"strin" + "g"
en"string"
; le résultat est inférieur à 20 caractères.intern()
fonction.intern
fonction dans Python 3 - il est déplacé vers sys.internCas 1
Cas 2
Maintenant, votre question est de savoir pourquoi l'identifiant est le même dans le cas 1 et non dans le cas 2.
Dans le cas 1, vous avez assigné une chaîne littérale
"123"
àx
ety
.Comme les chaînes sont immuables, il est logique que l'interpréteur stocke le littéral de chaîne une seule fois et pointe toutes les variables vers le même objet.
Par conséquent, vous voyez l'identifiant comme identique.
Dans le cas 2, vous modifiez à l'
x
aide de la concaténation. Les deuxx
ety
ont les mêmes valeurs, mais pas la même identité.Les deux pointent vers différents objets en mémoire. Par conséquent, ils ont différents
id
et l'is
opérateur est retournéFalse
la source
id(x) != id(x)
par exemple, parce que la chaîne a été déplacée dans le processus d'évaluation.x = "12" + "3"
enx = "123"
(concaténation de deux chaînes littérales dans une seule expression) de sorte que l'affectation effectue réellement la recherche et trouve la même chaîne "interne" que poury = "123"
.