在Python 2.7中,repr
的{{1}}返回最接近17位数的最接近的十进制数;这足够精确,可以唯一地标识每个可能的IEEE浮点值。 float
的{{1}}工作方式类似,但它将结果限制为12位数;对于大多数用途,这是一个更合理的结果,并使您免受二进制和十进制表示之间的细微差别。
Python 2演示:http://ideone.com/OKJtxv
str
在Python 3.2中显示float
和print str(1.4*1.5)
2.1
print repr(1.4*1.5)
2.0999999999999996
返回相同的内容。
Python 3演示:http://ideone.com/oAKRsb
str
是否有PEP描述了变更或其他负责人的陈述?
答案 0 :(得分:28)
不,没有PEP。错误跟踪器中有issue,Python开发人员邮件列表中有associated discussion。虽然我负责提出并实施变更,但我不能说这是我的想法:它是在与Guido在EuroPython 2010上的对话中产生的。
更多细节:正如在评论中已经提到的,Python 3.1为float的字符串repr
引入了一种新算法(后来反向移植到Python 2系列,因此它也出现在Python 2.7中)。作为这种新算法的结果,在提示符处键入的“短”十进制数具有相应的短表示。这消除了str
和repr
之间存在差异的现有原因之一,并且可以对str
和repr
使用相同的算法。因此,对于Python 3.2,在上面链接的讨论之后,str
和repr
变得相同。至于为什么:它使语言变得更小更清洁,并且在输出字符串时它删除了相当任意的12位数选择。 (在2.7之前的Python版本中,用于repr
的17位数的选择远非任意,顺便说一下:两个不同的IEEE 754 binary64浮点数在转换为带有17位有效数字的十进制时将具有不同的表示形式,并且17是具有此属性的最小整数。)
除了简单之外,还有一些不太明显的好处。 repr
与str
区别的一个方面是,repr
自动在容器中使用,这一点在过去一直让用户感到困惑。例如,在Python 2.7中:
>>> x = 1.4 * 1.5
>>> print x
2.1
>>> print [x]
[2.0999999999999996]
我确信至少有一个StackOverflow问题在某个地方询问这个现象:here is one such和another更新的问题。通过Python 3.2中引入的简化,我们得到了这个:
>>> x = 1.4 * 1.5
>>> print(x)
2.0999999999999996
>>> print([x])
[2.0999999999999996]
至少更一致。
如果您确实希望能够隐藏不精确,那么正确的方法仍然是相同的:使用字符串格式来精确控制输出格式。
>>> print("{:.12g}".format(x))
2.1
我希望这能解释改变背后的一些原因。我不打算认为这是普遍有益的:正如你所指出的,旧str
具有隐藏不精确的方便副作用。但在我看来(当然,我有偏见),它确实有助于从语言中消除一些惊喜。