字符串是否在内部存储为单独的字符,内存中的每个字符都由其他类似字符串共享?

Is string internally stored as individual characters, each character in memory shared by other similar strings?

例如,字符串var1 = 'ROB'是否存储为3个内存位置R,O和B,每个位置都有自己的地址,变量var1指向内存位置R?那怎么指向O和B呢?

其他字符串——例如:var2 = 'BOB'——指向内存中与var1相同的B和O吗?

这只是部分答案:

  • var1 是指代 字符串对象的名称 'ROB'.
  • var2 是引用另一个字符串对象的名称 'BOB'.

字符串对象如何存储各个字符,不同的字符串对象是否共享同一内存,我现在无法比"sometimes"和"it depends"更详细地回答。跟string interning有关,可以用

如何存储字符串是一个实现细节,但实际上,在 CPython 参考解释器上,它们存储为 C-style 字符数组。因此,如果 R 位于地址 x,则 O 位于 x+1(或 +2+4,具体取决于最大的序数值在字符串中),并且 B 位于 x+2(或 +4+8)。因为字母是连续存储的,所以知道 R 在哪里(以及 str 中的一个标志表示每个字符的存储量有多大)就足以找到 OB .

'BOB' 位于完全不同的地址,y,它的 OB 也是连续的。 'ROB' 中的 OB'BOB' 中的 OB 完全无关。

这有一个令人困惑的方面。如果您对字符串进行索引,并检查结果的 id,看起来 'O' 在两个字符串中具有相同的地址。但这只是因为:

  1. 索引到一个字符串 returns 一个 字符串,与被索引的字符串无关,并且
  2. CPython 在 latin-1 范围内缓存长度为 1 的字符串,所以 'O' 是一个单例(不管你怎么做,你都会得到缓存的字符串)

我会注意到现代 Python 中的实际 str 内部结构比我上面提到的还要复杂;单个字符串可能会在同一个对象中以最多三种不同的编码存储相同的数据(规范形式和用于使用特定 Python C API 的缓存版本)。除了使用 sys.getsizeof 检查大小外,从 Python 级别看不到它,因此通常不值得担心。

如果您真的想一头扎进杂草中,请随意阅读 PEP 393: Flexible String Representation,其中详细介绍了 CPython 3.3 中采用的新 str 对象结构的内部结构。