为什么'decimal.Decimal(1)'不是"数字"的实例。真的'?



我尝试检查变量是否是任何类型的数字(intfloatFractionDecimal等(的实例。

我遇到了这个问题及其答案:如何正确使用 python 的 isinstance(( 来检查变量是否为数字?

但是,我想排除复数,例如 1j .

该类看起来numbers.Real完美,但它返回False Decimal数字...

from numbers Real
from decimal import Decimal
print(isinstance(Decimal(1), Real))
# False

矛盾的是,例如,它适用于Fraction(1)

该文档描述了一些应该与数字一起使用的操作,我在十进制实例上测试了它们,没有任何错误。此外,十进制对象不能包含复数。

那么,isinstance(Decimal(1), Real)为什么要返回False呢?

所以,我直接在cpython/numbers.py的源代码中找到了答案:

## Notes on Decimal
## ----------------
## Decimal has all of the methods specified by the Real abc, but it should
## not be registered as a Real because decimals do not interoperate with
## binary floats (i.e.  Decimal('3.14') + 2.71828 is undefined).  But,
## abstract reals are expected to interoperate (i.e. R1 + R2 should be
## expected to work if R1 and R2 are both Reals).

事实上,在float中增加Decimal会引发TypeError

在我看来,它违反了最小惊讶原则,但并不重要。

作为解决方法,我使用:

import numbers
import decimal
Real = (numbers.Real, decimal.Decimal)
print(isinstance(decimal.Decimal(1), Real))
# True