Instagram上有this条帖子,作者说,如果num3
和num4
设置为257,并且num3 is num4
被评估,您应该得到False
。
我修改了代码,增加了一些条件,但是我得到了True
。我看到,直到256个整数被分配了相同的存储桶以表示相同的值,但以后没有分配257个。那是怎么回事?
num1 = 256
num2 = 256
if num1 == num2:
print(True)
num3 = 257
num4 = 257
if num3 == num4:
print(True)
if num3 is num4:
print(True)
else:
print(False)
答案 0 :(得分:3)
如果两个变量指向同一个对象,is将返回True
==如果变量引用的对象相等。
在脚本中运行:
是返回True
因为num3和num4都指向同一个对象:
# id() to get the unique identifier of an object
print(id(num3) , id(num4))
55080624 55080624
== 也返回True
num3 = 257
num4 = 257
两者均指<class 'int'> 257
在REPL中运行:
是返回False
因为num3和num4都指向不同的对象:
# id() to get the unique identifier of an object
print(id(num3) , id(num4))
34836272 39621264
== 返回True
num3 = 257
num4 = 257
两者均指<class 'int'> 257
结果不同的原因是Why does the `is` operator behave differently in a script vs the REPL?
在.py脚本中运行代码时,整个文件将被编译为 代码对象,然后再执行。在这种情况下,CPython能够 某些优化-例如为整数重用同一实例 300。
因此,在您的情况下,num3和num4均引用<class 'int'> 257
。在REPL中,您具有不同的对象ID,但是,如果您在脚本中运行文件,则将文件编译并优化为相同的对象ID之后。
关于256和257的不同行为:
"is" operator behaves unexpectedly with integers
What's with the integer cache maintained by the interpreter?
简而言之,代表值介于-5到+256之间的对象是在启动时创建的,因此,如果数字范围介于-5到256之间,则对于任何<-5和> 256的int,在REPL中都会获得相同的对象ID,它们将被分配给新的对象ID。
例如:
num5 = -6
num6 = -6
print(id(num5),id(num6))
39621232 39621136
num7 = 258
num8 = 258
print(id(num7),id(num8))
39621296 39621328
答案 1 :(得分:2)
如果再次查看该帖子,您会看到num3 == num4
为True,但是 num3 is num4
为False。这与项目ID有关。 ==
比较变量的值,而is
比较变量的id。您可以使用id(num3)
和id(num4)
查看其每个ID。当值大于256时,它们应该有所不同。原因是Python自动存储低数值,分配给这些低数值的变量将指向相同的ID。 Python之所以这样做,是因为它们是如此常用。但是直到Python需要它们时才创建更大的数字。因此,变量具有自己的ID。
编辑:
运行脚本与REPL时似乎有不同的行为。最初的Instagram帖子使用REPL,我使用REPL复制了False比较。不过,运行脚本对我来说是True。