【发布时间】:2021-01-09 03:26:12
【问题描述】:
您能否解释一下为什么在 Python v3.8 中会发生这种情况?
a=round(2.3)
b=round(2.4)
print(a,b)
print(type(a),type(b))
print(a is b)
print(id(a))
print(id(b))
输出:
2 2
<class 'int'> <class 'int'>
False
2406701496848
2406701496656
>>>
2 在小整数缓存的范围内。那么为什么会有不同的对象具有相同的值呢?
【问题讨论】:
-
小的 int 缓存不是保证,只是实现细节。从学术的角度来看,这个问题很有趣(我只是试图追踪它,它似乎应该从
round到float.__round__,它调用PyLong_FromDouble,对于小值将调用PyLong_FromLong,并且应该检查缓存,所以我不确定为什么它的行为不符合预期),但它是一个实现细节,而不是保证的细节,所以完全依赖它表明代码编写得很糟糕。 -
在 Python 3.9 中无法重现... :-)(但在 3.8 中可以)
-
@superbrain:找到了变化。代码路径更改为将 C
doubles 转换为PyLongs 的优化,并且它在小的int缓存检查中循环了副作用。 -
@ShadowRanger 啊,当我第一次看到这种变化时,我以为他们只是将优化从
__round__实现转移到现在的位置。但再看一遍,我发现它在__trunc__实现中。事实上,在 3.8 中,1.2.__round__() is 1给了我False,而1.2.__trunc__() is 1已经给了我True。
标签: python python-3.x integer