Python中的==和`is`是否有区别?

我的Google-fu让我失望了

在Python中,以下两个testing是否相等(ha!)?

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

这是否适用于你将比较实例的对象( list说)?

好吧,这样回答我的问题:

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

所以==testing值在哪里testing,看看他们是否是同一个对象?

如果两个variables指向相同的对象,则返回True如果variables引用的对象相等,则返回==

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

在你的情况下,第二个testing只工作,因为Pythoncaching小整数对象,这是一个实现细节。 对于较大的整数,这不起作用:

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

string文字也是如此:

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

请看这个问题 。

有一个简单的经验法则告诉你何时使用==或是。

  • ==价值平等 。 当你想知道两个对象是否具有相同的值时使用它。
  • 是供参考的平等 。 当你想知道两个引用是否指向同一个对象时使用它。

一般来说,当你比较一个简单types的东西时,你通常会检查值是否相等 ,所以你应该使用== 。 例如,你的例子的意图可能是检查x的值是否等于2( == ),而不是x是否字面意思是指与2相同的对象。


还有一点需要注意:由于CPython参考实现的工作方式,如果您错误地使用比较参考的整数相等性,您会得到意想不到的结果:

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

这几乎是我们所期望的: ab具有相同的值,但是是不同的实体。 但是这个呢?

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

这与以前的结果不一致。 这里发生了什么? 原来,由于性能原因,Python的参考实现caching范围为-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 

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

==确定值是否相等,而“is”则确定它们是否完全相同。

他们完全不同 。 检查对象身份,而==检查是否相等(一个概念取决于两个操作数的types)。

这只是一个幸运的巧合,“ is ”似乎与小整数正确工作(如5 == 4 + 1)。 这是因为CPython通过使整数在单独的范围内(-5到256)来优化整数的存储: https : //docs.python.org/2/c-api/int.html#c.PyInt_FromLong

https://docs.python.org/library/stdtypes.html#comparisons

istesting为了相同性==testing

每个(小)整数值映射到一个单一的值,所以每3个是相同的和相等的。 这是一个实现细节,不是语言规范的一部分

你的回答是正确的。 is运算符比较两个对象的身份。 ==运算符比较两个对象的值。

对象的身份一旦创build就不会改变; 你可以把它看作是内存中对象的地址。

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

看看堆栈溢出的问题Python的“是”运算符意外地用整数行为

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

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

有一个,也是唯一一个NoneType的例子,即None是一个单例。 因此foo == Nonefoo is None意思是一样的。 然而,testing更快,Pythonic惯例是使用foo is None

如果你正在对垃圾收集进行一些自省或反省,或者检查你的定制string实习小工具是否工作或类似,那么你可能有一个用于foobar

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

其实我想把这个作为一个评论添加,但不能很好的美化,所以作为一个答案,请不要把它当作答案。

这是我所了解的 –

逐一执行,理解每一步的输出

 a = [1,2] b = [1,2,3] b.pop() id(a) id(b) a is b a == b 

“==”比较值

“是”比较潜在的对象

 # this pgm is to show you the diff b/n == and is # a==b and a is b # == compares values # is compares references ie compares wether two variables refer to same object(memory) a=10 b=10 print(a==b) # returns True as a,b have same value 10 print(a is b) # returns True, # we usually falsey assume that a =10 a new object . b=10 a new obj created # but actually when b=10 ,nothing but b is pointed to 10 until value of a or b is changed from 10 a=[1] b=[1] print(a==b) #returns True as a,b have a list element 1 print(a is b) #returns False because here two different objs are created when initiated with lists 

如果o1和o2都指向内存中相同的物理位置(换句话说,如果它们是相同的对象),则o1是o2 =>

o1 == o2 =>这里python调用o1的__cmp __(o2)方法,理想情况下应该比较值并返回True或False。 (换句话说,它比较价值)

对于JAVA人:

  • 在Java中,通过使用str1 == str2来确定两个stringvariables是否引用相同的物理内存位置。 (称为对象身份,它是用Python编写的, 因为str1是str2 )。

  • 在Java中比较string值, usestr1.equals(str2) ; 在Python中,使用str1 == str2

例:

 class A(): ...: def __init__(self,a): ...: self.a = a ...: def __repr__(self): ...: return str(self.a) ...: def __cmp__(self, value): ...: print self.a ...: print value.a ...: return cmp(self.a, value.a) 

Python Shell输出:

o = A(2)o1 = o

o == o1 2 2是真的

o是o1是真的

o1 = A(2)

o是o1错误

虽然所有这些依赖于实现exception指针比较和值比较的答案都可能是正确的,但使用的更深层次的语法原因is确定variables值是否为None (在布尔逻辑中通常表示为NULL )。

在关系数据库和其他逻辑系统中, NULL意味着实际值是“未知的”。 因此,逻辑expression式xx == NULL必须始终计算为NULL本身,因为不可能知道xx (无论它的值是什么)与未知值相同。 在严格遵守布尔逻辑规则的编程语言中, xx == NULL (或Pythonically xx == None )正确计算为NULL ,必须提供其他方法来确定variables值是否为NULL 。 由于对象引用None的单一性质,Python在这方面是一个离群值。 但是为了清晰和逻辑的正确性,使用Python is比较运算符,对我来说似乎更加健全的做法。