“是”运算符意外与浮游物行为 [英] 'is' operator behaves unexpectedly with floats

查看:156
本文介绍了“是”运算符意外与浮游物行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当单元测试一个模块时,我遇到了一个令人困惑的问题。模块实际上是铸造值,我想比较这个值。

== (部分地,我要小心这个区别)

pre $ code >>>> 0.0是0.0
正如预期的那样#
>>> float(0.0)是0.0
真正的#如预期

正如预期的那样,是我的问题:

 >>> float(0)是0.0 
False
>>> float(0)是float(0)
False

为什么?至少最后一个真的让我感到困惑。 float(0) float(0.0)的内部表示应该相等。与 == 的比较工作正常。

解决方案

如何做的作品。它检查引用而不是值。它返回 True ,如果两个参数分配给同一个对象的话。

在这种情况下,它们是不同的实例。 float(0) float(0)具有相同的值 == ,但就Python而言是不同的实体。 CPython实现还将整数作为单例对象缓存在此范围内 - > [x | x∈ℤ∧-5≤x≤256]

 >>> 0.0是0.0 
True
>>> float(0)是float(0)#不一样的引用,唯一的实例。
False

在这个例子中,我们可以演示整数缓冲原理:

 >>> a = 256 
>>> b = 256
>>> a是b
True
>>> a = 257
>>> b = 257
>>> a是b
False

现在,如果将float传递给在float()中,浮点文字被简单地返回( short-circuited ),就像在同一个引用中一样,因为不需要从现有的实例化一个新的float float:

 >>> 0.0是0.0 
True
>>> float(0.0)是float(0.0)
True

这可以通过使用 int()也是:​​

 >>> int(256.0)是int(256.0)#相同的引用,缓存。 
True
>>> int(257.0)是int(257.0)#返回不同的引用,不缓存。
False
>>> 257是257#相同的参考。
True
>>> 257.0是257.0#相同的参考。正如@Martijn Pieters指出的那样。
True

然而,的结果是也取决于它的执行范围(超出了这个问题/解释范围),请参考用户: @ 吉姆 代码对象。甚至python的文档也包含了这个行为的一部分:

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆