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

时间:2019-07-12 07:58:18

标签: python python-internals

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

其他字符串(例如:var2 = 'BOB')是否指向var1所指向的内存中的B和O?

2 个答案:

答案 0 :(得分:4)

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

'BOB'的地址完全不同,y,并且其OB也是连续的。 OB中的'ROB'OB中的'BOB'完全无关。

这有一个令人困惑的方面。如果您在字符串中建立索引,然后检查结果的id,似乎'O'在两个字符串中都具有相同的地址。但这仅仅是因为:

  1. 索引到字符串中会返回与被索引的字符串无关的 new 字符串,并且
  2. CPython缓存长度为latin-1范围内的一个字符串,因此'O'是一个单例(无论如何创建,都可以取回缓存的字符串)

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

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

答案 1 :(得分:0)

这只是部分答案:

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

一个字符串对象如何存储各个字符,以及不同的字符串对象是否共享相同的内存,我现在无法比“有时”和“取决于”更详细地回答。它与可能使用的string interning有关。