两个字符串变量被设置为相同的值。s1 == s2总是返回True,但s1 = s2有时返回False。

如果我打开我的Python解释器,并做同样的比较,它成功了:

>>> s1 = 'text'
>>> s2 = 'text'
>>> s1 is s2
True

为什么会这样?


当前回答

根据我有限的Python使用经验,is用于比较两个对象,以确定它们是否是相同的对象,而不是具有相同值的两个不同对象。==用于确定两个值是否相同。

这里有一个很好的例子:

>>> s1 = u'public'
>>> s2 = 'public'
>>> s1 is s2
False
>>> s1 == s2
True

s1是Unicode字符串,s2是普通字符串。它们不是相同的类型,但它们的值相同。

其他回答

Is是同一性测试,==是相等性测试。在你的代码中发生的事情将在解释器中模拟,就像这样:

>>> a = 'pub'
>>> b = ''.join(['p', 'u', 'b'])
>>> a == b
True
>>> a is b
False

所以,难怪它们不一样,对吧?

换句话说,a等于b等于id(a) == id(b)

==运算符测试值等价性。is操作符测试对象的身份,Python测试两者是否真的是相同的对象(即,在内存中存在相同的地址)。

>>> a = 'banana'
>>> b = 'banana'
>>> a is b
True

在这个例子中,Python只创建了一个字符串对象,并且a和b都指向它。原因是Python内部缓存和重用一些字符串作为优化。内存中实际上只有一个字符串'banana',由a和b共享。为了触发正常行为,你需要使用更长的字符串:

>>> a = 'a longer banana'
>>> b = 'a longer banana'
>>> a == b, a is b
(True, False)

当你创建两个列表时,你会得到两个对象:

>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> a is b
False

在这种情况下,我们会说这两个列表是等价的,因为它们有相同的元素,但不相同,因为它们不是同一个对象。如果两个对象是相同的,它们也是等效的,但如果它们是等效的,它们就不一定相同。

如果a指向一个对象,你赋值b = a,那么两个变量指向同一个对象:

>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True

参考:Allen B. Downey的《Python 2e》

is关键字是测试对象身份,而==是值比较。

如果使用is,当且仅当对象是同一对象时,结果将为真。但是,当对象的值相同时,==将为真。

如果你不确定你在做什么,使用'=='。 如果你对它有更多的了解,你可以用'is'来表示已知的对象,比如'None'。

否则,你最终会想知道为什么事情不管用,为什么会发生这种情况:

>>> a = 1
>>> b = 1
>>> b is a
True
>>> a = 6000
>>> b = 6000
>>> b is a
False

我甚至不确定在不同的Python版本/实现之间是否保证有一些东西保持不变。

这是一个边注,但在惯用的Python中,你经常会看到这样的东西:

if x is None:
    # Some clauses

这是安全的,因为保证有一个Null对象的实例(即None)。