可能重复:
Python “is” operator behaves unexpectedly with integers
今天我试着调试我的项目,经过几个小时的分析,我得到了这样的结果:
>>> (0-6) is -6
False但,
>>> (0-5) is -5
True你能给我解释一下为什么吗?也许这是某种bug或非常奇怪的行为。
> Python 2.7.3 (default, Apr 24 2012, 00:00:54) [GCC 4.7.0 20120414 (prerelease)] on linux2
>>> type(0-6)
<type 'int'>
>>> type(-6)
<type 'int'>
>>> type((0-6) is -6)
<type 'bool'>
>>> 发布于 2012-07-14 02:29:38
从-5到256 (包括-5到256)的所有整数都被缓存为与CPython共享相同地址的全局对象,因此is测试通过。
这个工件在http://www.laurentluce.com/posts/python-integer-objects-implementation/中有详细的解释,我们可以在http://hg.python.org/cpython/file/tip/Objects/longobject.c中检查当前的源代码。
一种特定的结构用于引用小整数并共享它们,因此访问速度很快。它是一个由262个指向整数对象的指针组成的数组。这些整数对象是在初始化期间在我们上面看到的整数对象块中分配的。小整数的范围是-5到256。许多Python程序花费大量时间使用该范围内的整数,因此这是一个明智的决定。
这只是CPython的一个实现细节,你不应该依赖它。例如,PyPy实现了integer的id以返回自身,因此即使它们在内部是“不同的对象”,(0-6) is -6也始终为真;它还允许您配置是否启用这种整数缓存,甚至设置下限和上限。但一般来说,从不同来源检索的对象不会完全相同。如果您想比较相等,只需使用==。
发布于 2012-07-14 02:30:26
Python将-5 - 256范围内的整数存储在解释器中:它有一个整数对象池,从中返回这些整数。这就是为什么这些对象是相同的:(0-5)和-5,而不是(0-6)和-6,因为它们是在现场创建的。
以下是CPython源代码中的源代码:
#define NSMALLPOSINTS 257
#define NSMALLNEGINTS 5
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];(view CPython source code:/trunk/Objects/intobject.c)。源代码包含以下注释:
/* References to small integers are saved in this array so that they
can be shared.
The integers that are saved are those in the range
-NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/然后,is运算符会将它们(-5)进行相等比较,因为它们是相同的对象(相同的内存位置),但另外两个新整数(-6)将位于不同的内存位置(然后is不会返回True)。请注意,上面源代码中的257是针对正整数的,因此它是0 - 256 (包含)。
(source)
发布于 2012-07-14 02:30:13
这不是个bug。is不是一个相等性测试。==会给出预期的结果。
这种行为的技术原因是,Python实现可以自由地将相同常量值的不同实例视为相同的对象或不同的对象。出于节省内存的原因,您正在使用的Python实现选择让某些小常量共享同一个对象。您不能依赖于此行为是相同的版本,或者跨不同的Python实现。
https://stackoverflow.com/questions/11476190
复制相似问题