我的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.

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


当前回答

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

其他回答

你的答案是正确的。is操作符比较两个对象的标识符。==操作符比较两个对象的值。

对象的标识一旦创建就不会改变;你可以把它看作是对象在内存中的地址。

你可以通过定义__cmp__方法或像__eq__这样的富比较方法来控制对象值的比较行为。

他们中的大多数人已经回答到点子上了。只是作为一个额外的说明(基于我的理解和实验,但不是来自文档来源),声明

如果变量引用的对象相等,则==

从以上答案应读为

如果变量引用的对象相等且属于相同类型/类的对象==

. 我根据下面的测试得出了这个结论:

list1 = [1,2,3,4]
tuple1 = (1,2,3,4)

print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))

print(list1 == tuple1)
print(list1 is tuple1)

这里,列表和元组的内容是相同的,但类型/类是不同的。

简而言之,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是参考等式。当您想知道两个引用是否指向同一个对象时,可以使用它。

一般来说,当你比较一个简单类型时,你通常会检查值是否相等,所以你应该使用==。例如,您的示例的目的可能是检查x是否有一个等于2的值(==),而不是检查x是否字面上指的是与2相同的对象。


另外需要注意的是:由于CPython引用实现的工作方式,如果你错误地使用is比较整数上的引用相等性,你会得到意外和不一致的结果:

>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False

这和我们预期的差不多:a和b有相同的值,但是不同的实体。但是这个呢?

>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True

这与先前的结果不一致。这是怎么回事?事实证明,Python的参考实现缓存范围为-5..出于性能考虑,将256作为单例实例。下面是一个例子:

>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
... 
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False

这是不使用的另一个明显原因:当您错误地将其用于值相等时,行为将留给实现。

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

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