Un autre doublon demandait pourquoi deux chaînes é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 ne sont-ils pas la même chaîne? Surtout compte tenu de ceci:
>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True
Retardons un peu la deuxième partie. Comment le premier pourrait-il être vrai?
L'interpréteur devrait avoir une "table interne", une table mappant des valeurs de chaîne à des objets de chaîne, donc chaque fois que vous essayez de créer une nouvelle chaîne avec le contenu 'abc'
, vous récupérez le même objet. Wikipedia a une discussion plus détaillée sur le fonctionnement du stage.
Et Python a une table interne de chaînes; vous pouvez manuellement interner des chaînes avec la sys.intern
méthode.
En fait, Python est autorisé à interner automatiquement tous les types immuables, mais pas obligé de le faire. Différentes implémentations intègreront différentes valeurs.
CPython (l'implémentation que vous utilisez si vous ne savez pas quelle implémentation vous utilisez) auto-interne de petits entiers et certains singletons spéciaux comme False
, mais pas des chaînes (ou de grands entiers, ou de petits tuples, ou autre chose). Vous pouvez voir cela 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 étaient z
et w
identiques?
Ce n'est pas l'interpréteur qui effectue automatiquement l'internation, ce sont les valeurs de repli du compilateur.
Si la même chaîne 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 comme un littéral de chaîne, parce que r'abc'
, 'abc'
et 'a' 'b' 'c'
sont toutes différentes littéraux , 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 aller encore plus loin: 'ab' + 'c'
peut être converti en 'abc'
par l'optimiseur, auquel cas il peut être plié avec une 'abc'
constante dans le même module.
Encore une fois, c'est quelque chose que Python est autorisé mais pas obligé de faire. Mais dans ce cas, CPython plie toujours de petites chaînes (et aussi, par exemple, de petits tuples). (Bien que le compilateur instruction par instruction de l'interpréteur interactif n'exécute pas la même optimisation que le compilateur module à la fois, vous ne verrez donc pas exactement les mêmes résultats de manière interactive.)
Alors, que devez-vous faire à ce sujet en tant que programmeur?
Eh bien… rien. Vous n'avez presque jamais aucune raison de vous soucier si deux valeurs immuables sont identiques. Si vous voulez savoir quand vous pouvez utiliser à la a is b
place 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 de singleton comme
x is None
.
- Pour les valeurs mutables, lorsque vous avez besoin de savoir si la mutation
x
affectera le y
.