首页 > 解决方案 > 为什么“num3 is num4”会导致 False?

问题描述

Instagram 上有这篇文章,作者说如果num3num4设置为 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)

标签: pythonpython-3.xintpython-internals

解决方案


如果两个变量指向同一个对象,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

==返回真

num3 = 257
num4 = 257

正如两者所指<class 'int'> 257

你有不同结果的原因是为什么 `is` 运算符在脚本和 REPL 中的行为不同?

当您在 .py 脚本中运行代码时,整个文件会在执行之前编译为代码对象。在这种情况下,CPython 能够进行某些优化——比如为整数 300 重用同一个实例。

因此,在您的情况下, num3 和 num4 均指<class 'int'> 257. 在 REPL 中你有不同的对象 id,但是如果你在脚本中运行它们,在文件被编译并优化为相同的对象 id 之后。

关于 256 和 257 的不同行为:

"is" 运算符对整数的行为异常

解释器维护的整数缓存是怎么回事?

简而言之,表示值从 -5 到 +256 的对象是在启动时创建的,因此如果您的数字范围为 -5 到 256,那么您在 REPL 中将获得相同的对象 ID,对于任何 int <-5 和 > 256,它们将是分配给一个新的对象ID。

例如 :

num5 = -6
num6 = -6 

print(id(num5),id(num6))

39621232 39621136

num7 = 258
num8 = 258

print(id(num7),id(num8))

39621296 39621328

推荐阅读