奇怪的是:
>>> a = 123
>>> b = 123
>>> a is b
True
>>> a = 123.
>>> b = 123.
>>> a is b
False
似乎a is b
或多或少被定义为id(a) == id(b)
。以这种方式制作错误很容易:
basename, ext = os.path.splitext(fname)
if ext is '.mp3':
# do something
else:
# do something else
有些fnames意外地在else块中结束了。修复很简单,我们应该使用ext == '.mp3'
代替,但表面上if ext is '.mp3'
似乎是一种很好的pythonic方式来编写它,它比“正确”的方式更具可读性。
由于字符串是不可变的,为什么它的错误有哪些技术细节?什么时候更好地进行身份检查,什么时候检查更好?
答案 0 :(得分:22)
它们根本不同。
==
通过调用__eq__
方法is
才返回所以与Java说比较:
is
与对象的==
相同==
与对象的equals
相同答案 1 :(得分:10)
据我所知,is
检查对象标识的等价性。因为没有必要的“字符串实习”,所以恰好在序列中碰巧具有相同字符的两个字符串通常不是相同的字符串对象。
从字符串中提取子字符串(或者,实际上是序列中的任何子序列)时,最终会得到两个不同的对象,包含相同的值。
因此,当且仅当您比较对象标识时,才使用is
。比较值时使用==
。
答案 2 :(得分:7)
确定是否使用的简单规则是或者在Python中使用==
这是一个简单的规则(除非你想在Python解释器或构建框架中使用Python对象做有趣的事情):
仅用于无比较。
if foo is None
否则使用==。
if x == 3
然后你是安全的。在上述评论中已经解释了这个的基本原理。如果你不是100%确定为什么要这样做,请不要使用。
答案 3 :(得分:0)
定义像这样的类作为API中使用的常量的默认值也很有用。在这种情况下,使用is = ==运算符会更正确。
class Sentinel(object):
"""A constant object that does not change even when copied."""
def __deepcopy__(self, memo):
# Always return the same object because this is essentially a constant.
return self
def __copy__(self):
# called via copy.copy(x)
return self
答案 4 :(得分:0)
当您将is
与带有警告之类的文字一起使用SyntaxWarning: "is" with a literal. Did you mean "=="?
时,PyCharm会警告您。因此,与文字比较时,请始终使用==
。否则,您可能更喜欢使用is
来通过对象的引用比较对象。