首页 > 解决方案 > python 3.6 和更早版本与 3.7 中不可变对象的“is”行为不一致

问题描述

当我注意到 python(v3.6 和更早版本)和(v3.7)之间的行为不一致时,我正在向我的学生介绍is运算符。

启动 python shell 并运行:

5/2 is 2.5

或者:

(1, 2, 3) is (1, 2, 3)

在 v3.6.X 中你可以得到False两者,但在 v3.7 中它们变成了True.

我的期望是结果应该是 True 因为我认为不可变的数字对象(或它们的元组)只有一个实例。

看来至少我的想法在以前的 Python 版本中是不对的。

有谁知道已经做出了哪些改变来解释这种新行为?

标签: pythonpython-3.xinternals

解决方案


我不确定原因和来源,但我的猜测是这与内联优化有关。

如果您为此值分配变量,则身份检查将产生False,与以前相同。

>>> 5/2 is 2.5
True
>>> a = 5/2
>>> a is 2.5
False

关于新折叠优化的有趣说明。由于 python 是“所有运行时”,因此无法优化前面的某些内容,但它会努力解析尽可能多的范围:

>>> a = 3.14
>>> b = 3.14
>>> a is b
False
>>> a = 3.14; b = 3.14
>>> a is b
True

推荐阅读