以下是示例:
>>> 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__
方法是否对小字符串或?进行缓存?
有人可以解释一下吗?
答案 0 :(得分:4)
有一个原因,为什么修改字符串不是goint来修改第二个字符串。
python中的字符串是不可变的。
并不完全是字符串在python中缓存,但事实是你无法改变它们。 python解释器能够稍微优化并将两个名称引用到相同的id。
在python中,你永远不会直接编辑字符串。看看这个:
a = "fun"
a.capitalize()
print a
>> fun
大写功能将创建a
的大写版本,但不会更改a
。一个例子是str.replace
。您可能已经注意到,要使用replace更改字符串,您必须执行以下操作:
a = "fun"
a = a.replace("u", "a")
print a
>> fan
您在此处看到的是名称a
正在影响指向“有趣”的指针。在第二行,如果没有相似的字符串,我们会影响{{1}}的新ID,旧的a
可能会被gc删除。
你必须要理解的是,因为字符串是不可变的,所以python可以安全地将字符串指向同一个id。由于字符串永远不会被修改。你不能拥有一个会被隐含修改的字符串。
此外,您会看到其他类型的数字也是不可变的,并且与ids的行为相同。但不要被ids愚弄,因为出于某些原因,我无法解释。
任何大于256的数字都会收到不同的ID,即使它们指向相同的值。如果我没弄错的话,使用更大的字符串,ID也会有所不同。
注意:强>
在repl或程序本身内部评估代码时,id事物也可能具有不同的值。我记得有一个代码使用代码块进行优化。这意味着在不同的行上执行代码可能足以阻止优化。
以下是REPL中的一个示例:
a
有了数字:
>>> 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)
但是作为python脚本执行文件会打印,因为它执行相同代码块中的行(据我所知)
>>> a = 100000
>>> b = 100000
>>> id(a), id(b)
(140533800516256, 140533800516304)
>>> a = 100000; b = 100000
>>> id(a), id(b)
(140533800516232, 140533800516232)
答案 1 :(得分:2)
字符串不会被缓存 - 它们实际上是相同的字符串。
请参阅,Python中的字符串是不可变的。就像数字1
是相同的数字1
一样,无论您在代码中的哪个位置编写它,字符串"Hello"
都是相同 string,无论你在代码中的哪个位置写它。
由于它是不可变的,你也不能像列表或某些内容那样就地更改它 - 例如,如果你调用list.reverse()
,它会更改原始列表,但是如果你调用{{1它,返回一个新字符串,旧字符串不受影响(这意味着它是不可变的)。因为你不能改变那个字符串,所以Python中有两个不同的str.replace("a", "b")
副本没有任何意义,因为它们都意味着完全相同的东西而都不会改变。< / em>的
编辑 - @Keeper指出,有一个section of the Python FAQ详细说明为什么字符串是不可变的,因此它们的行为就像这样。 Link
答案 2 :(得分:0)
python中的字符串未缓存:)
a = 'a'
b = 'a'
id(a) == id(b) = id('a') # True because share same constant object id('a')!
a = 'z' # it change 'a' but a is not referencing 'b' so you can not change b
id(a) == id('z') # not a contains 'z' but since not related to b, b contains still 'a'!
你可以做这样的事情来实现你想要的:
Thing(object): # Dummy object can store any field since it is Python
pass
a = Thing()
a.str = 'a'
b = a
print b.str # return 'a' since reference to object is same!
a.str = 'b'
print b.str # return 'b' since reference to object is same but value changed!