何时使用==以及何时使用?

时间:2011-07-04 10:41:44

标签: python memory equality

奇怪的是:

>>> 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方式来编写它,它比“正确”的方式更具可读性。

由于字符串是不可变的,为什么它的错误有哪些技术细节?什么时候更好地进行身份检查,什么时候检查更好?

5 个答案:

答案 0 :(得分:22)

它们根本不同。

  1. ==通过调用__eq__方法
  2. 进行比较 当且仅当两个引用属于同一个对象时,
  3. is才返回
  4. 所以与Java说比较:

    1. is与对象的==相同
    2. ==与对象的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来通过对象的引用比较对象。