This is implementation-specific, but your interpreter is probably interning compile-time constants but not the results of run-time expressions.
In what follows I use CPython 2.7.3.
In the second example, the expression "strin"+"g"
is evaluated at compile time, and is replaced with "string"
. This makes the first two examples behave the same.
If we examine the bytecodes, we'll see that they are exactly the same:
# s1 = "string"
2 0 LOAD_CONST 1 ('string')
3 STORE_FAST 0 (s1)
# s2 = "strin" + "g"
3 6 LOAD_CONST 4 ('string')
9 STORE_FAST 1 (s2)
The third example involves a run-time concatenation, the result of which is not automatically interned:
# s3a = "strin"
# s3 = s3a + "g"
4 12 LOAD_CONST 2 ('strin')
15 STORE_FAST 2 (s3a)
5 18 LOAD_FAST 2 (s3a)
21 LOAD_CONST 3 ('g')
24 BINARY_ADD
25 STORE_FAST 3 (s3)
28 LOAD_CONST 0 (None)
31 RETURN_VALUE
If you were to manually intern()
the result of the third expression, you'd get the same object as before:
>>> s3a = "strin"
>>> s3 = s3a + "g"
>>> s3 is "string"
False
>>> intern(s3) is "string"
True
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…