答案 0 :(得分:249)
==
是相等测试。它检查右手侧和左手侧是否是相同的对象(根据他们的__eq__
或__cmp__
方法。)
is
是身份测试。它检查右手侧和左手侧是否是同一个物体。没有方法调用,对象不能影响is
操作。
您使用is
(和is not
)作为单身人士,例如None
,您不关心可能想要假装为None
的对象或其他地方您希望在与None
进行比较时防止对象中断。
答案 1 :(得分:127)
首先,让我谈谈几个条款。如果您只想回答问题,请向下滚动到“回答您的问题”。
对象标识:创建对象时,可以将其分配给变量。然后,您还可以将其分配给另一个变量。而另一个。
>>> button = Button()
>>> cancel = button
>>> close = button
>>> dismiss = button
>>> print(cancel is close)
True
在这种情况下,cancel
,close
和dismiss
都指向内存中的同一个对象。您只创建了一个Button
对象,并且所有三个变量都引用了这一个对象。我们说cancel
,close
和dismiss
都是指相同的对象;也就是说,它们指的是一个单独的对象。
对象相等性:比较两个对象时,通常不关心它是否指向内存中的 exact 相同对象。通过对象相等,您可以为两个对象的比较定义自己的规则。当您撰写if a == b:
时,您基本上是在说if a.__eq__(b):
。这允许您在__eq__
上定义a
方法,以便您可以使用自己的比较逻辑。
基本原理:两个对象具有完全相同的数据,但不完全相同。 (它们在记忆中不是同一个对象。) 示例:字符串
>>> greeting = "It's a beautiful day in the neighbourhood."
>>> a = unicode(greeting)
>>> b = unicode(greeting)
>>> a is b
False
>>> a == b
True
注意:我在这里使用unicode字符串,因为Python足够聪明,可以重用常规字符串而无需在内存中创建新字符串。
在这里,我有两个unicode字符串,a
和b
。它们具有完全相同的内容,但它们在内存中不是同一个对象。但是,当我们比较它们时,我们希望它们相等。这里发生的是unicode对象实现了__eq__
方法。
class unicode(object):
# ...
def __eq__(self, other):
if len(self) != len(other):
return False
for i, j in zip(self, other):
if i != j:
return False
return True
注意:__eq__
上的unicode
肯定比这更有效。
基本原理:两个对象具有不同的数据,但如果某些关键数据相同,则会被视为同一个对象。 示例:大多数类型的模型数据
>>> import datetime
>>> a = Monitor()
>>> a.make = "Dell"
>>> a.model = "E770s"
>>> a.owner = "Bob Jones"
>>> a.warranty_expiration = datetime.date(2030, 12, 31)
>>> b = Monitor()
>>> b.make = "Dell"
>>> b.model = "E770s"
>>> b.owner = "Sam Johnson"
>>> b.warranty_expiration = datetime.date(2005, 8, 22)
>>> a is b
False
>>> a == b
True
在这里,我有两台戴尔监视器,a
和b
。他们有相同的品牌和型号。但是,它们既没有相同的数据,也没有相同的内存对象。但是,当我们比较它们时,我们希望它们相等。这里发生的是Monitor对象实现了__eq__
方法。
class Monitor(object):
# ...
def __eq__(self, other):
return self.make == other.make and self.model == other.model
与None
比较时,请始终使用is not
。 None是Python中的单例 - 在内存中只有一个实例。
通过比较身份,可以非常快速地执行此操作。 Python检查您所引用的对象是否与全局None对象具有相同的内存地址 - 这是对两个数字进行非常非常快速的比较。
通过比较 equality ,Python必须查找您的对象是否具有__eq__
方法。如果没有,它会检查每个超类,寻找__eq__
方法。如果找到一个,Python会调用它。如果__eq__
方法很慢并且当它注意到另一个对象是None
时没有立即返回,那么这尤其糟糕。
您没有实施__eq__
吗?然后Python可能会在__eq__
上找到object
方法,而是使用它 - 它只是检查对象身份。
在比较Python中的大多数其他内容时,您将使用!=
。
答案 2 :(得分:24)
请考虑以下事项:
class Bad(object):
def __eq__(self, other):
return True
c = Bad()
c is None # False, equivalent to id(c) == id(None)
c == None # True, equivalent to c.__eq__(None)
答案 3 :(得分:15)
None
是单身,因此身份比较将始终有效,而对象可以通过.__eq__()
伪造相等比较。
答案 4 :(得分:7)
>>> () is () True >>> 1 is 1 True >>> (1,) == (1,) True >>> (1,) is (1,) False >>> a = (1,) >>> b = a >>> a is b True
有些对象是单例,因此is
与它们等同于==
。大多数都没有。