Un autre duplicata demandait pourquoi deux cordes égales ne sont généralement pas identiques, ce qui n'est pas vraiment répondu ici :
>>> x = 'a'
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False
Alors, pourquoi ce n'est pas la même chaîne ? Surtout si l'on tient compte de ceci :
>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True
Remettons la deuxième partie à plus tard. Comment la première partie pourrait-elle être vraie ?
L'interpréteur devrait disposer d'une "table d'internage", une table de correspondance entre les valeurs des chaînes de caractères et les objets chaîne de caractères, de sorte qu'à chaque fois que vous essayez de créer une nouvelle chaîne de caractères avec le contenu 'abc'
vous récupérez le même objet. Wikipedia propose une discussion plus détaillée sur le fonctionnement des stages.
Et Python a une table d'internage de chaînes de caractères ; vous pouvez internaliser manuellement des chaînes de caractères avec la fonction sys.intern
méthode.
En fait, Python est autorisé pour internaliser automatiquement tout type immuable, mais pas requis pour le faire. Des implémentations différentes interneront des valeurs différentes.
CPython (l'implémentation que vous utilisez si vous ne savez pas quelle implémentation vous utilisez) internalise automatiquement les petits entiers et certains singletons spéciaux tels que False
mais pas les chaînes de caractères (ni les grands entiers, ni les petits tuples, ni rien d'autre). Vous pouvez le constater assez facilement :
>>> a = 0
>>> a += 1
>>> b = 1
>>> a is b
True
>>> a = False
>>> a = not a
>>> b = True
a is b
True
>>> a = 1000
>>> a += 1
>>> b = 1001
>>> a is b
False
OK, mais pourquoi z
y w
identique ?
Ce n'est pas l'interpréteur qui s'interpose automatiquement, c'est le compilateur qui plie les valeurs.
Si la même chaîne de caractères en temps de compilation apparaît deux fois dans le même module (ce que cela signifie exactement est difficile à définir - ce n'est pas la même chose qu'une chaîne littérale, parce que r'abc'
, 'abc'
y 'a' 'b' 'c'
sont tous des littéraux différents mais la même chaîne - mais facile à comprendre intuitivement), le compilateur ne créera qu'une seule instance de la chaîne, avec deux références.
En fait, le compilateur peut même aller plus loin : 'ab' + 'c'
peut être converti en 'abc'
par l'optimiseur, auquel cas elle peut être repliée avec une 'abc'
constant dans le même module.
Encore une fois, c'est quelque chose que Python est autorisé à faire mais n'est pas obligé de le faire. Mais dans ce cas, CPython plie toujours les petites chaînes de caractères (et aussi, par exemple, les petits tuples). (Bien que le compilateur statement-by-statement de l'interpréteur interactif n'exécute pas la même optimisation que le compilateur module-at-a-time, vous ne verrez donc pas exactement les mêmes résultats de manière interactive).
Alors, que faire en tant que programmeur ?
Eh bien rien. Vous n'avez presque jamais de raison de vous soucier de savoir si deux valeurs immuables sont identiques. Si vous voulez savoir quand vous pouvez utiliser a is b
au lieu de a == b
vous posez la mauvaise question. Il suffit de toujours utiliser a == b
sauf dans deux cas :
- Pour des comparaisons plus lisibles avec les valeurs singleton comme
x is None
.
- Pour les valeurs mutables, lorsque vous avez besoin de savoir si la mutation
x
aura une incidence sur le y
.