为什么 "num3 is num4" 会导致 False?
Why should "num3 is num4" result in False?
Instagram 上有 this post 作者说如果 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)
如果您再次查看 post,您会发现 num3 == num4
是 True, 但 num3 is num4
是 False。这与项目 ID 有关。 ==
比较变量的值,而 is
比较它们的 id。您可以使用 id(num3)
和 id(num4)
查看他们的每个 ID。当值高于 256 时它们应该不同。原因是 Python 自动存储低数值,分配给这些低数值的变量将指向相同的 id。 Python 这样做是因为它们很常用。但是直到 Python 需要它们时才会创建更大的数字。所以变量有自己的ID。
编辑:
运行 脚本与 REPL 似乎有不同的行为。最初的 Instagram post 使用的是 REPL,我使用 REPL 复制了 False 比较。 运行 一个脚本对我来说是正确的。
is will return True if two variables point to the same object
== if the objects referred to by the variables are equal.
运行 在脚本中:
is returns True
因为 num3 和 num4 都指向同一个对象:
# id() to get the unique identifier of an object
print(id(num3) , id(num4))
55080624 55080624
== also returns True
num3 = 257
num4 = 257
因为两者都指的是 <class 'int'> 257
运行 在 REPL 中:
is returns False
因为 num3 和 num4 指向不同的对象:
# id() to get the unique identifier of an object
print(id(num3) , id(num4))
34836272 39621264
== returns True
num3 = 257
num4 = 257
因为两者都指的是 <class 'int'> 257
你有不同结果的原因是 Why does the `is` operator behave differently in a script vs the REPL?
When you run code in a .py script, the entire file is compiled into a
code object before executing it. In this case, CPython is able to make
certain optimizations - like reusing the same instance for the integer
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,你在 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
Instagram 上有 this post 作者说如果 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)
如果您再次查看 post,您会发现 num3 == num4
是 True, 但 num3 is num4
是 False。这与项目 ID 有关。 ==
比较变量的值,而 is
比较它们的 id。您可以使用 id(num3)
和 id(num4)
查看他们的每个 ID。当值高于 256 时它们应该不同。原因是 Python 自动存储低数值,分配给这些低数值的变量将指向相同的 id。 Python 这样做是因为它们很常用。但是直到 Python 需要它们时才会创建更大的数字。所以变量有自己的ID。
编辑:
运行 脚本与 REPL 似乎有不同的行为。最初的 Instagram post 使用的是 REPL,我使用 REPL 复制了 False 比较。 运行 一个脚本对我来说是正确的。
is will return True if two variables point to the same object
== if the objects referred to by the variables are equal.
运行 在脚本中:
is returns True
因为 num3 和 num4 都指向同一个对象:
# id() to get the unique identifier of an object
print(id(num3) , id(num4))
55080624 55080624
== also returns True
num3 = 257
num4 = 257
因为两者都指的是 <class 'int'> 257
运行 在 REPL 中:
is returns False
因为 num3 和 num4 指向不同的对象:
# id() to get the unique identifier of an object
print(id(num3) , id(num4))
34836272 39621264
== returns True
num3 = 257
num4 = 257
因为两者都指的是 <class 'int'> 257
你有不同结果的原因是 Why does the `is` operator behave differently in a script vs the REPL?
When you run code in a .py script, the entire file is compiled into a code object before executing it. In this case, CPython is able to make certain optimizations - like reusing the same instance for the integer 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,你在 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