什么时候用==,什么时候用is?

问题描述 投票:0回答:6

奇怪的是:

>>> a = 123
>>> b = 123
>>> a is b
True
>>> a = 123.
>>> b = 123.
>>> a is b
False

似乎

a is b
或多或少被定义为
id(a) == id(b)
。这样很容易出bug:

basename, ext = os.path.splitext(fname)
if ext is '.mp3':
    # do something
else:
    # do something else

一些 fname 意外地出现在 else 块中。解决方法很简单,我们应该使用

ext == '.mp3'
来代替,但尽管如此,从表面上看
if ext is '.mp3'
似乎是一种很好的 Python 编写方式,而且它比“正确”方式更具可读性。

既然字符串是不可变的,那么它错误的技术细节是什么?什么时候进行身份检查更好,什么时候进行平等检查更好?

python memory equality
6个回答
23
投票

它们本质上是不同的。

  1. ==
    通过调用
    __eq__
    方法进行比较
  2. is
    当且仅当两个引用指向同一个对象时才返回 true

与 Java 相比:

  1. is
    与对象的
    ==
    相同
  2. ==
    与对象的
    equals
    相同

21
投票

据我所知,

is
检查对象身份等价性。由于没有强制的“字符串驻留”,因此恰好序列中具有相同字符的两个字符串通常不是同一个字符串对象。

当您从字符串中提取子字符串(或者实际上是序列中的任何子序列)时,您最终将得到两个包含相同值的不同对象。

因此,当且仅当您比较对象身份时才使用

is
。比较值时使用
==


18
投票

在 Python 中确定是否使用 is 或 == 的简单规则

这里有一个简单的规则(除非你想了解 Python 解释器的理论或构建框架用 Python 对象做有趣的事情):

仅用于

None
比较。

if foo is None

否则使用==。

if x == 3

那么你就安全了。其基本原理已在上述评论中进行了解释。如果您不能 100% 确定为什么要这样做,请不要使用 is。


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

0
投票

当您将

is
与带有警告(例如
SyntaxWarning: "is" with a literal. Did you mean "=="?
)的文字一起使用时,PyCharm 应该会向您发出警告。因此,在与文字进行比较时,请始终使用
==
。否则,您可能更喜欢使用
is
来通过对象的引用来比较对象。


0
投票

我认为这个答案缺少一个明确的例子,说明在比较非

is
的对象时,何时真正使用
None

几个物体,例如列表,当分配给其他变量时保留对象引用而不是创建对象的副本。如果没有正确理解,这可能会导致不良行为:

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

但是,如果您创建同一对象的多个实例,它们具有相同的定义,但本质上是不同的对象:

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

说到

None
,那就是特例了。
None
是一个单例对象,因此,
None
的实例化仅限于一个对象。因此,使用
None
运算符测试对象是否为
is
总是有效的。

>>> a = None
>>> b = a
>>> b_ = None
>>> a is None
True
>>> b is a
True
>>> b_ is a
True
>>> b_ == a
True
>>> b == None
True

总之,只要你想知道两个变量都指向同一个对象,就使用

is
,也就是说,如果你改变
a
的状态,
b
也会改变。

© www.soinside.com 2019 - 2024. All rights reserved.