为什么在Python中Decimal('0') > 9999.0 为真?
这和我之前的问题有点关系,具体可以看看这个链接:为什么在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 个回答
在编程中,有时候我们需要处理一些数据,比如从一个地方获取数据,然后把它放到另一个地方。这就像是把书从一个书架搬到另一个书架一样。
有些时候,我们会遇到一些问题,比如数据的格式不对,或者数据不完整。这就像是你在搬书的时候,发现有些书是破的,或者缺了一页。这时候,我们就需要想办法修复这些问题,确保所有的数据都是完整和正确的。
在这个过程中,我们可能会用到一些工具和方法,帮助我们更有效地处理这些数据。就像搬家时用箱子装书,可以让搬运变得更轻松。
总之,处理数据就像是搬书,需要耐心和细心,确保每一本书都能安全到达新的地方。
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
因为 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
不理解浮点数。它在内部明确检查操作数的类型,只认long
、int
和Decimal
。是的,这算是个 bug,因为意外的库实现会导致后续出现问题。要是能做得更好,或者直接抛出一个TypeException
就好了。结果它抛出的NotImplemented
错误就像在比较 Decimal 和某个员工记录的哈希值时一样。- 接着尝试了一些其他的比较操作,但比较最终放弃了。
- 然后调用了 CPython 的 Objects/object.c/default_3way_compare 中的默认比较。
- 在 Python 3 中,这个比较会出错。在 Python 2 中,它会比较 id() 函数。
- 在 Windows 系统上,会使用不区分大小写的比较(有点像)。在现代系统上,会使用区分大小写的比较。
- 所以你会得到不同的结果。
我们到了吗?