例子如下:
>>> 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
