Skip to main content
 首页 » 编程设计

python之为什么字符串对象被缓存在python中

2025年05月04日30think

例子如下:

>>> first_string = str('This_is_some_how_cached') 
>>> second_string = str('This_is_some_how_cached') 
>>> id(first_string) == id(second_string) 
True 
>>> first_string = str('This_is_new_string') 
>>> second_string 
'This_is_some_how_cached' 
>>> 

在上面的示例中,first_string 和 second_string 的创建方式不同,但它们具有相同的 id,这意味着它们指向相同的引用?如果是,当我将 first_string 更改为某个新字符串时,不会更新 second_string。字符串类中的这个 python __new__ 方法是对小字符串的一种缓存还是?

有人能解释一下吗?

请您参考如下方法:

那么修改一个字符串不会修改第二个字符串是有原因的。

Python 中的字符串是不可变的。

这并不完全是字符串被缓存在 python 中,但事实是您无法更改它们。 python 解释器能够进行一些优化并将两个名称引用到相同的 id。

在 python 中,您实际上永远不会直接编辑字符串。看看这个:

a = "fun" 
a.capitalize() 
print a 
>> fun 

capitalize 函数将创建大写版本的 a 但不会更改 a。一个例子是 str.replace。您可能已经注意到,要使用 replace 更改字符串,您必须执行如下操作:

a = "fun" 
a = a.replace("u", "a") 
print a 
>> fan 

您在这里看到的是名称 a 受到指向“fun”的指针的影响。在第二行,我们正在影响 a 的新 id,如果没有类似的字符串,旧的 a 可能会被 gc 删除。

您必须了解的是,由于字符串是不可变的,python 可以安全地让字符串指向相同的 id。因为字符串永远不会被修改。您不能拥有将被隐式修改的字符串。

此外,您还会看到一些其他类型(例如数字)也是不可变的,并且与 ID 的行为相同。但不要被 ID 愚弄,因为某些我无法解释的原因。

任何大于 256 的数字都会收到不同的 ID,即使它们指向相同的值。如果我没记错的话,字符串越大,id 也会不同。

注意:

当代码在 repl 或程序本身中被评估时,id 也可能有不同的值。我记得有一件事是用代码块优化代码。这意味着在不同的行上执行代码可能足以阻止优化。

这是 REPL 中的示例:

>>> a = '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]'; b = '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]' 
>>> id(a), id(b) 
(4561897488, 4561897488) 
 
>>> a = '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]' 
>>> b = '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]' 
>>> id(a), id(b) 
(4561897416, 4561897632) 

用数字:

>>> a = 100000 
>>> b = 100000 
>>> id(a), id(b) 
(140533800516256, 140533800516304) 
 
>>> a = 100000; b = 100000  
>>> id(a), id(b) 
(140533800516232, 140533800516232)  

但是将文件作为 python 脚本执行会打印出来,因为它执行同一代码块中的行(据我所知)

4406456232 4406456232 
4406456232 4406456232 
140219722644160 140219722644160