CPython字符串大于21个字符 - 内存分配

时间:2016-06-15 17:35:51

标签: python python-3.x memory cpython

我想知道这种行为的原因是什么(CPython 2.7和3.5):

>>> a = 's' ; b = 's'
>>> id(a), id(b)
(4322870976, 4322870976)

短于21个字符的字符串似乎共享相同的内存地址(或id)。

>>> a = 's' * 20 ; b = 's' * 20
>>> id(a), id(b)
(4324218680, 4324218680)

从21开始,此行为会发生变化。

>>> a = 's' * 21 ; b = 's' * 21
>>> id(a), id(b)
(4324218536, 4324218608)

我无法找到合理的解释,但根据python docs

  

例如,a = 1之后; b = 1,a和b可能会或可能不会引用值为1的同一对象,具体取决于实现...

在查看cpython's code之后,我无法找到做出此决定的地方。

1 个答案:

答案 0 :(得分:3)

Python编译器converts尽可能多的表达式,并且在字节码中对常量(即它实例化它们)有意义。具有相同值的常量将通过此过程具有相同的id()。这给出了第一和第二个例子中的结果。

但我们必须符合“有道理”的资格。大的表达式(例如10**100)会导致大量空间用于其常量结果。这意味着编译器在字节码中包含未修改的表达式,并在运行时计算它们的值。对于字符串(实际上所有类型),最大长度为20,因此第三个示例中的表达式由VM而不是编译器进行评估。