`==`运算符何时不等于`is`运算符? (蟒蛇)

时间:2010-09-05 20:32:21

标签: python comparison equality

我注意到我可以使用==运算符来比较所有本机数据类型(整数,字符串,布尔值,浮点数等)以及包含本机数据类型的列表,元组,集合和字典。在这些情况下,==运算符检查两个对象是否相等。但在其他一些情况下(尝试比较我创建的类的实例),==运算符只检查两个变量是否引用同一个对象(因此在这些情况下==运算符等同于{{ 1}}运营商)

我的问题是:is运营商什么时候做的不仅仅是比较身份?

编辑:我正在使用Python 3

4 个答案:

答案 0 :(得分:19)

在Python中,==运算符是根据magic method __eq__实现的,默认情况下通过身份比较来实现它。但是,您可以覆盖该方法,以提供您自己的对象相等概念。请注意,如果您这样做,通常还会至少覆盖__ne__(实现!=运算符)和__hash__,它会计算实例的哈希码。

我发现,即使在Python中,我的__eq__实现也符合Java语言中为equals方法的实现规定的规则,即:

  • 它是自反的:对于任何非空引用值x,x.equals(x)应该返回true。
  • 它是对称的:对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true。
  • 它是传递性的:对于任何非空引用值x,y和z,如果x.equals(y)返回true而y.equals(z)返回true,则x.equals(z)应返回true
  • 它是一致的:对于任何非空引用值x和y,x.equals(y)的多次调用始终返回true或始终返回false,前提是没有修改在对象上的equals比较中使用的信息。
  • 对于任何非空引用值x,x.equals(null)应返回false。

最后一个应该用null取代None,但是这些规则在Python中并不像在Java中那么容易。

答案 1 :(得分:18)

==is在概念上总是不同的:前者委托给左手对象的__eq__ [1],后者总是检查身份,没有任何委托。让你感到困惑的是object.__eq__(默认情况下由用户编码的类继承,当然不会覆盖它!)是以身份的形式实现的(毕竟,是{{1}绝对没有来检查除了它的身份,那么还有什么可能呢?! - )。

[1]为了简单起见,省略了object方法的遗留概念,这只是一个边缘并发症,并且在段落的要点中没有任何重要的改变; - )。

答案 2 :(得分:7)

==不仅仅涉及在涉及整数时比较身份。它不只是检查两个整数是否是同一个对象;它实际上确保了它们的值匹配。考虑:

>>> x=10000
>>> y=10000
>>> x==y,x is y
(True, False)
>>> del x
>>> del y
>>> x=10000
>>> y=x
>>> x==y,x is y
(True, True)

“标准”Python实现在幕后为小内容做了一些事情,所以当用小值测试时,你可能会得到不同的东西。将其与等效的10000案例进行比较:

>>> del y
>>> del x
>>> x=1
>>> y=1
>>> x==y,x is y
(True, True)

答案 3 :(得分:4)

最重要的一点是建议总是使用:

if myvalue is None:

if myvalue == None:

永远不要使用:

if myvalue is True:

但请使用:

if myvalue:

这一点后来对我来说并不是那么明确,因为我认为有时候将布尔值True与其他True值分开,比如“Alex Martelli”,说“Alex Martelli”中没有False(绝对不是,它甚至引发异常:))但是“Alex Martelli”中存在“(就像在任何其他字符串中一样)。