尽管这个问题在实际中没有任何实际用途,但我对Python如何进行字符串实习感到好奇。我注意到以下内容。

>>> "string" is "string"
True

这是我所期望的。

您也可以这样做。
>>> "strin"+"g" is "string"
True

那真是太聪明了!

但是您不能这样做。
>>> s1 = "strin"
>>> s2 = "string"
>>> s1+"g" is s2
False

Python为什么不评估s1+"g"并意识到它与s2相同并将其指向相同的地址?最后一块使返回False实际发生了什么?

最佳答案

这是特定于实现的,但是您的解释器可能是内部编译时常量,而不是运行时表达式的结果。

接下来,我使用CPython 2.7.3。

在第二个示例中,表达式"strin"+"g"在编译时求值,并替换为"string"。这使得前两个示例的行为相同。

如果我们检查字节码,我们会发现它们是完全相同的:

  # 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)

第三个示例涉及运行时串联,其结果不会自动中断:
  # 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

如果您要手动对第三个表达式的结果进行intern()编码,则将获得与以前相同的对象:
>>> s3a = "strin"
>>> s3 = s3a + "g"
>>> s3 is "string"
False
>>> intern(s3) is "string"
True

07-26 06:01