Answers:
==
是一项平等测试。它检查右侧和左侧是否是相等的对象(根据它们__eq__
或__cmp__
方法)。
is
是身份测试。它检查右侧和左侧是否是同一对象。没有方法调用完成,对象不能影响is
操作。
您可以将is
(和is not
)用于单例,例如None
,您不关心可能假装为的对象,None
或者想要与之进行比较时要防止对象破裂的地方None
。
None
方法很少,几乎没有属性。如果您的__eq__
测试需要一个方法或属性,则可能会中断。 def __eq__( self, other ): return self.size == other.size
。例如,如果other
碰巧会中断None
。
is
就像Java一样==
。Python ==
就像Java一样.equals()
。当然,这只有在您了解Java的情况下才有用。
is
是===
(非常相等),反之is not
则是!==
(不完全相等)。
is not
单个运算符,还是只是否定is
内部like 的结果not foo is bar
?
首先,让我再谈几个问题。如果您只是想回答问题,请向下滚动到“回答问题”。
对象标识:创建对象时,可以将其分配给变量。然后,您也可以将其分配给另一个变量。还有一个。
>>> button = Button()
>>> cancel = button
>>> close = button
>>> dismiss = button
>>> print(cancel is close)
True
在这种情况下,cancel
,close
,和dismiss
都指的是同一个对象在内存中。您仅创建了一个Button
对象,并且所有三个变量都引用了该对象。我们说cancel
,close
和dismiss
都指同一对象; 也就是说,它们只引用一个对象。
对象相等性:比较两个对象时,通常不必关心它是否指向内存中完全相同的对象。使用对象相等性,您可以定义自己的规则以比较两个对象。当您写作时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__
on 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
。在Python中,没有一个是单例的-内存中只有一个实例。
通过比较身份,可以非常快速地执行此操作。Python检查您所引用的对象是否与全局None对象具有相同的内存地址-两个数字的非常非常快速的比较。
通过比较相等性,Python必须检查您的对象是否具有__eq__
方法。如果不是,它将检查每个超类以寻找一种__eq__
方法。如果找到一个,Python会调用它。如果该__eq__
方法很慢并且在注意到另一个对象为时不立即返回,则尤其糟糕None
。
你没有实现__eq__
吗?然后,Python可能会找到该__eq__
方法object
并改用该方法-无论如何,它只会检查对象的身份。
在Python中比较大多数其他内容时,您将使用!=
。
考虑以下:
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)
None
是单例,因此身份比较将始终有效,而对象可以通过伪造相等比较.__eq__()
。
None
,但是关于None
对其他类型实施平等的副作用可能会出现不正确的行为。它不仅仅涉及安全性,还涉及正确性。
>>>()是() 真正 >>> 1是1 真正 >>>(1,)==(1,) 真正 >>>(1,)是(1,) 假 >>> a =(1,) >>> b = a >>> a是b 真正
有些对象是单例,因此is
与它们等效==
。大多数不是。
()
而1
不是固有单身。
-NSMALLNEGINTS <= n <= NSMALLPOSINTS
)和空元组是单例。实际上,它没有记录或保证,但不太可能更改。