我的Google-fu让我失望了

在Python中,以下两个相等测试是否等效?

n = 5
# Test one.
if n == 5:
    print 'Yay!'

# Test two.
if n is 5:
    print 'Yay!'

这是否适用于对象,你将比较实例(一个列表说)?

这就回答了我的问题

L = []
L.append(1)
if L == [1]:
    print 'Yay!'
# Holds true, but...

if L is [1]:
    print 'Yay!'
# Doesn't.

所以==测试值测试是看他们是否相同的对象?


当前回答

看看Stack Overflow问题Python的“is”运算符对整数的行为出人意料。

它主要归结为“is”检查它们是否是相同的对象,而不仅仅是彼此相等(256以下的数字是一个特殊情况)。

其他回答

==确定值是否相等,而is确定它们是否完全相同的对象。

如果两个变量指向同一个对象(在内存中),则返回True,如果变量引用的对象相等则返回==。

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

# Make a new copy of list `a` via the slice operator, 
# and assign it to variable `b`
>>> b = a[:] 
>>> b is a
False
>>> b == a
True

在您的情况下,第二个测试只能工作,因为Python缓存小整数对象,这是一个实现细节。对于较大的整数,这行不通:

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True

这同样适用于字符串字面量:

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

请看这个问题。

简而言之,is检查两个引用是否指向同一个对象。==检查两个对象是否具有相同的值。

a=[1,2,3]
b=a        #a and b point to the same object
c=list(a)  #c points to different object 

if a==b:
    print('#')   #output:#
if a is b:
    print('##')  #output:## 
if a==c:
    print('###') #output:## 
if a is c:
    print('####') #no output as c and a point to different object 

它们完全不同。Is检查对象的同一性,而==检查相等性(这一概念取决于两个操作数的类型)。

这只是一个幸运的巧合,“is”似乎正确地适用于小整数(例如5 == 4+1)。这是因为CPython通过使整数为单例来优化范围(-5到256)内的整数的存储。这种行为完全依赖于实现,并且不能保证在所有形式的小型转换操作下都能保留。

例如,Python 3.5也创建了短字符串单例,但将它们切片会破坏这种行为:

>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False

正如John Feminella所说,大多数情况下您将使用==和!=,因为您的目标是比较值。我只是想把剩下的时间里你会做的事情分类:

有且只有一个实例的NoneType,即None是一个单例。因此,foo == None和foo is None意思相同。然而,is测试更快,并且python惯例是使用foo is None。

如果您正在进行一些自省或垃圾收集,或检查定制的字符串实习小工具是否工作或诸如此类,那么您可能有foo is bar的用例。

True和False(现在)也是单例,但是没有foo == True的用例,也没有foo is True的用例。