首页 > 解决方案 > Python交互终端结果与脚本结果不一致

问题描述

交互式终端结果:

In [11]: a=1111111111111111111111111111111111111111111111111111

In [12]: b=1111111111111111111111111111111111111111111111111111

In [13]: a is b
Out[13]: False

脚本结果:

# overflow in ~ [13:55:16]
» python -c "a=1111111111111111111111111111111111111111111111111111;b=1111111111111111111111111111111111111111111111111111; print a is b"

True

嗯嗯。我认为结果应该是 False... 因为1111111111111111111111111111111111111111111111111111256

我知道is不是平等测试。但是,当 Python 声明一个变量(不可变类型)时,例如b = 1,它会查明该对象是否已在旧 object( a = 1) 中声明。如果对象被声明(a = 1),变量将直接指向旧对象,不会申请新的内存空间。(a is bTrue

In [2]: a=1

In [3]: b=1

In [4]: a is b
Out[4]: True

嗯。正确的?

至于“is”运算符对整数的行为出乎意料。它解释了 的用法is,但我仍然不明白为什么这两种方法会导致不同的结果。:(

也许,它只取决于 Python 实现和运行时环境。

标签: python

解决方案


这真的取决于你在找什么。用于is身份测试和==平等测试。不要依赖is检查是否相等。

相等是指对象的值,而标识是指指向同一对象 id 的指针。例如,如果您在终端中运行它,is将返回False

a = 1111
b = int('1111')

print(a == b)
>>True
print(a is b)
>>False

不建议使用is不用于身份测试的假设,其行为取决于 Python 实现和运行时环境。我也怀疑是因为 Python 如何读取重复的整数。再举一个例子:

a = 257
b = 257
a is b
>>False

从文档:

返回值:新引用。创建一个值为 ival 的新整数对象。

当前的实现为 -5 到 256 之间的所有整数保留一个整数对象数组,当您在该范围内创建一个 int 时,您实际上只是取回了对现有对象的引用。所以应该可以改变 1 的值。我怀疑 Python 在这种情况下的行为是未定义的。:-)

为了优化,短整数实际上只是指回同一个对象,如果您在上面的值(非重复)中更改了单个数字,这也应该适用256,它将返回False


推荐阅读