Cela dépend de l'implémentation, mais votre interpréteur interagit probablement avec les constantes de compilation, mais pas avec les résultats des expressions d'exécution.
Dans ce qui suit, CPython 3.9.0+ est utilisé.
Dans le deuxième exemple, l'expression "strin"+"g"
est évaluée à la compilation et est remplacée par "string"
. Les deux premiers exemples se comportent donc de la même manière.
Si nous examinons les bytecodes, nous verrons qu'ils sont exactement les mêmes :
# s1 = "string"
1 0 LOAD_CONST 0 ('string')
2 STORE_NAME 0 (s1)
# s2 = "strin" + "g"
2 4 LOAD_CONST 0 ('string')
6 STORE_NAME 1 (s2)
Ce bytecode a été obtenu avec (qui imprime quelques lignes supplémentaires après ce qui précède) :
import dis
source = 's1 = "string"\ns2 = "strin" + "g"'
code = compile(source, '', 'exec')
print(dis.dis(code))
Le troisième exemple concerne une concaténation au moment de l'exécution, dont le résultat n'est pas automatiquement interné :
# s3a = "strin"
3 8 LOAD_CONST 1 ('strin')
10 STORE_NAME 2 (s3a)
# s3 = s3a + "g"
4 12 LOAD_NAME 2 (s3a)
14 LOAD_CONST 2 ('g')
16 BINARY_ADD
18 STORE_NAME 3 (s3)
20 LOAD_CONST 3 (None)
22 RETURN_VALUE
Ce bytecode a été obtenu avec (qui imprime quelques lignes supplémentaires avant ce qui précède, et ces lignes sont exactement les mêmes que dans le premier bloc de bytecodes donné ci-dessus) :
import dis
source = (
's1 = "string"\n'
's2 = "strin" + "g"\n'
's3a = "strin"\n'
's3 = s3a + "g"')
code = compile(source, '', 'exec')
print(dis.dis(code))
Si vous deviez manuellement sys.intern()
le résultat de la troisième expression, vous obtiendrez le même objet que précédemment :
>>> import sys
>>> s3a = "strin"
>>> s3 = s3a + "g"
>>> s3 is "string"
False
>>> sys.intern(s3) is "string"
True
De plus, Python 3.9 affiche un avertissement pour les deux dernières instructions ci-dessus :
Avertissement syntaxique : "est" avec un littéral. Vouliez-vous dire "==" ?