为什么在Python中 "hello" is "hello"
的结果会是 True
?
我在这里读到了以下内容:
如果两个字符串字面量相等,则它们被放置在同一内存位置上。字符串是不可变的实体,不会有任何损害。
那么,每个Python字符串在内存中只有一个地方?听起来很奇怪。这里到底发生了什么?
为什么在Python中 "hello" is "hello"
的结果会是 True
?
我在这里读到了以下内容:
如果两个字符串字面量相等,则它们被放置在同一内存位置上。字符串是不可变的实体,不会有任何损害。
那么,每个Python字符串在内存中只有一个地方?听起来很奇怪。这里到底发生了什么?
Python(与Java、C、C++和.NET一样)使用字符串池/内部化。解释器意识到“hello”与“hello”相同,因此它会优化并使用内存中的相同位置。
另一个好处:"hell" + "o"是"hello"
==> True
a = 'hell' + 'o!'
和b = 'hello!'
,那么a is b
将会是false。a = 'hell' + 'o'
和b = 'hello'
确实触发了内部化,所以它们是相等的。但是把这两个例子放到一个函数中,你又会得到相同的对象。有多种重用对象的方法,它们无疑是优化的结果。不要依赖于这些实现细节。 - Martijn Pieters那么每个Python字符串在内存中只有一个位置吗?
不是的,只有解释器决定优化的字符串才会被放在唯一的位置上。这个决策是基于并非语言规范的策略做出的,而且在不同的CPython版本中可能会发生变化。
例如,在我的安装(2.6.2 Linux)中:
>>> 'X'*10 is 'X'*10
True
>>> 'X'*30 is 'X'*30
False
对于整数类型同样适用:
>>> 2**8 is 2**8
True
>>> 2**9 is 2**9
False
所以不要指望一个字符串就是那个字符串:即使只看C的实现,也不安全。==
。 - SingleNegationEliminationa = 50; b = 50; a is b
是True,a = 500; b = 500; a is b
是False。 - Darshan Chaudhary500
是一个字面常量,存储在代码对象中,而a
和b
都被赋予了这个常量...再次强调,这只是一个实现细节,不能保证一定成立。 - Martijn Pieters字面字符串可能会根据它们的哈希值或类似的东西进行分组。两个相同的字面字符串将存储在同一段内存中,并且所有引用都指向那个位置。
Memory Code
-------
| myLine = "hello"
| /
|hello <
| \
| myLine = "hello"
-------
is
操作符会在两个参数是同一个对象时返回 true。你的结果是由此产生的,以及引用的那一部分。
对于字符串字面值,它们是被池化(interned)的,这意味着它们会与已知的字符串进行比较。如果已经有一个相同的字符串,则该字面值将采用该值,而不是另一个值。因此,它们变成了同一个对象,表达式为真。
Python解释器/编译器会解析字符串字面量,即带引号的字符列表。当它这样做时,它可以检测到“我之前看过这个字符串”,并使用上次相同的表示。它能够做到这一点,因为它知道以这种方式定义的字符串是不能被更改的。
为什么这很奇怪呢?如果字符串是不可变的,只存储一次就有很多意义。.NET也有相同的行为。
我认为如果任何两个变量(不仅仅是字符串)包含相同的值,该值将只存储一次而不是两次,并且两个变量都将指向同一个位置。这可以节省内存。
id
函数以检查内存位置:print id("hello")
- Blixt