为什么在Python中Decimal('0') > 9999.0 为真?

5 投票
2 回答
748 浏览
提问于 2025-04-15 20:19

这和我之前的问题有点关系,具体可以看看这个链接:为什么在Python中''>0是True?

在Python 2.6.4中:

>> Decimal('0') > 9999.0
True

根据我之前问题的回答,我了解到在Python 2.x中比较不同类型的对象时,它们的类型是按名称排序的。但是在这个例子中:

>> type(Decimal('0')).__name__ > type(9999.0).__name__
False

那为什么 Decimal('0') > 9999.0 == True 呢?

更新:我通常在Ubuntu上工作(Linux 2.6.31-20-generic #57-Ubuntu SMP 2010年2月8日09:05:19 UTC i686 GNU/Linux,Python 2.6.4 (r264:75706, 2009年12月7日, 18:45:15) [GCC 4.4.1] 在linux2上)。在Windows(WinXP Professional SP3,Python 2.6.4 (r264:75706, 2009年11月3日, 13:23:17) [MSC v.1500 32位 (Intel)] 在win32上)时,我的原始语句表现得不一样:

>> Decimal('0') > 9999.0
False

我现在更加困惑了。%-(

2 个回答

1

在编程中,有时候我们需要处理一些数据,比如从一个地方获取数据,然后把它放到另一个地方。这就像是把书从一个书架搬到另一个书架一样。

有些时候,我们会遇到一些问题,比如数据的格式不对,或者数据不完整。这就像是你在搬书的时候,发现有些书是破的,或者缺了一页。这时候,我们就需要想办法修复这些问题,确保所有的数据都是完整和正确的。

在这个过程中,我们可能会用到一些工具和方法,帮助我们更有效地处理这些数据。就像搬家时用箱子装书,可以让搬运变得更轻松。

总之,处理数据就像是搬书,需要耐心和细心,确保每一本书都能安全到达新的地方。

def __gt__(self, other, context=None):
    other = _convert_other(other)
    if other is NotImplemented:
        return other
    ans = self._compare_check_nans(other, context)
    if ans:
        return False
    return self._cmp(other) > 0


def _convert_other(other, raiseit=False):
    """Convert other to Decimal.

    Verifies that it's ok to use in an implicit construction.
    """
    if isinstance(other, Decimal):
        return other
    if isinstance(other, (int, long)):
        return Decimal(other)
    if raiseit:
        raise TypeError("Unable to convert %s to Decimal" % other)
    return NotImplemented
12

因为 decimal 模块只会和 long、int 和 Decimal 这几种类型进行比较。对于其他类型,decimal 会默默地把它们当作“大于”的对象处理。你可以在 decimal.py 的 _convert_other() 函数中看到这种行为。

真是让人无奈的 Decimal 类。

哦,看看这个链接 http://bugs.python.org/issue2531

那么,事情是这样的:

  • 解释器会调用 Decimal.__gt__ 这个比较函数。
  • Decimal.__gt__ 会调用 Decimal._convert_other 来把传入的浮点数转换成 Decimal。
  • Decimal._convert_other 不理解浮点数。它在内部明确检查操作数的类型,只认 longintDecimal。是的,这算是个 bug,因为意外的库实现会导致后续出现问题。要是能做得更好,或者直接抛出一个 TypeException 就好了。结果它抛出的 NotImplemented 错误就像在比较 Decimal 和某个员工记录的哈希值时一样。
  • 接着尝试了一些其他的比较操作,但比较最终放弃了。
  • 然后调用了 CPython 的 Objects/object.c/default_3way_compare 中的默认比较。
  • 在 Python 3 中,这个比较会出错。在 Python 2 中,它会比较 id() 函数。
  • 在 Windows 系统上,会使用不区分大小写的比较(有点像)。在现代系统上,会使用区分大小写的比较。
  • 所以你会得到不同的结果。

我们到了吗?

撰写回答