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
这几乎是我们所期望的: a
和b
具有相同的值,但是是不同的实体。 但是这个呢?
>>> 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
is
testing为了相同性==
testing
每个(小)整数值映射到一个单一的值,所以每3个是相同的和相等的。 这是一个实现细节,不是语言规范的一部分
你的回答是正确的。 is
运算符比较两个对象的身份。 ==
运算符比较两个对象的值。
对象的身份一旦创build就不会改变; 你可以把它看作是内存中对象的地址。
您可以通过定义__cmp__
方法或像__eq__
这样的丰富比较方法来控制对象值的比较行为。
看看堆栈溢出的问题Python的“是”运算符意外地用整数行为 。
主要归结为“ is
”检查是否它们是相同的对象,不只是相等(256以下的数字是特殊情况)。
正如John Feminella所说,大多数情况下你会使用==和!=因为你的目标是比较值。 我只想分类你会做剩下的时间:
有一个,也是唯一一个NoneType的例子,即None是一个单例。 因此foo == None
和foo is None
意思是一样的。 然而,testing更快,Pythonic惯例是使用foo is None
。
如果你正在对垃圾收集进行一些自省或反省,或者检查你的定制string实习小工具是否工作或类似,那么你可能有一个用于foo
是bar
。
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
比较运算符,对我来说似乎更加健全的做法。