两个字符串变量被赋予相同的值。s1 == s2
永远返回 True
,但是 s1 is s2
有时会返回 False
。
如果我在Python解释器中执行同样的 is
比较,它会成功:
>>> s1 = 'text'
>>> s2 = 'text'
>>> s1 is s2
True
为什么会这样?
两个字符串变量被赋予相同的值。s1 == s2
永远返回 True
,但是 s1 is s2
有时会返回 False
。
如果我在Python解释器中执行同样的 is
比较,它会成功:
>>> s1 = 'text'
>>> s2 = 'text'
>>> s1 is s2
True
为什么会这样?
我相信这被称为“字符串驻留”。Python、Java、C和C++都会在优化模式下进行编译,如果使用两个相同的字符串,它们会指向同一块内存,而不是浪费内存创建两个字符串对象。
这使得Python的“is”运算符返回True,因为具有相同内容的两个字符串指向同一个字符串对象。这也会发生在Java和C中。
然而,这只对节省内存有用。您不能依赖它来测试字符串的相等性,因为各种解释器、编译器和JIT引擎并不总是能够实现这一点。
is
运算符用于检查对象的唯一性,而 == 运算符用于检查相等性。
从语言参考中可以得知:类型几乎影响对象行为的所有方面。甚至某种程度上会影响到对象唯一性的重要性:对于不可变类型而言,计算新值的操作可能实际上会返回引用相同类型和值的任何现有对象,但对于可变对象则不允许这样做。例如,a=1;b=1之后,a和b可能指向同一具有值为1的对象,也可能不是,这取决于具体实现方式;但c=[];d=[]之后,c和d将保证指向两个不同、独立的新创建的空列表。(注意,c=d=[]会将同一对象分配给c和d)。
由此可见,对于字符串、整数和元组这些不可变类型,使用 "is" 检查可能会失败,而使用 "==" 检查可能会成功。is
会比较内存地址,用于对象级别比较。
==
会比较程序中的变量,用于值级别检查。
is
检查内存地址的等价性。
==
检查值级别的等价性。
is
是身份测试,而 ==
是相等性测试(请参见 Python 文档)。
在大多数情况下,如果 a is b
,那么 a == b
。但是也有例外,例如:
>>> nan = float('nan')
>>> nan is nan
True
>>> nan == nan
False
is
进行身份测试,而不能进行相等性测试。
input = raw_input("Decide (y/n): ")
来读取控制台输入时,也会出现这个问题。在这种情况下,“y”作为输入并使用if input == 'y':
会返回“True”,而使用if input is 'y':
会返回False。 - Semjon Mössinger