Python number base class 或者如何判断一个值是一个数字

Python number base class OR how to determine a value is a number

Python 似乎缺少 "all numbers" 的基础 class,e。 G。 intfloatcomplexlong(在 Python2 中)。这对我来说很不幸,有点不方便。

我正在编写一个将数据类型相互匹配的函数(树匹配/搜索算法)。为此,我想测试 lists、dicts、strings 或 "numbers" 的输入值。四种情况分别处理,但我不想区分intlongfloatcomplex(虽然后者可能不会出现) .如果所有数字类型都派生自基本类型 number,这将很容易实现,但不幸的是,它们不是,AFAICS。

这种明确性的实施使得不寻常的 complex 被包含在内变得显而易见。这通常会提出我不想考虑的问题。我的设计宁愿说 "all number types" 而不是那个明确的列表。我也不想明确列出来自其他库(如 numpy 或类似库)的所有可能的数字类型。

第一个问题,比较理论化:为什么设计者不让所有数字类型都继承一个共同的数字基数class?这是否有充分的理由,也许是关于它的理论似乎不推荐?还是为以后的 Python 版本提出这个想法是否有意义?

第二个问题,更实用的一个:是否有推荐的方法来检查一个值是否为数字,也许是我不知道的库调用?使用 isinstance(x, (int, float, complex, long)) 的直接版本对我来说确实像一个离合器,与 Python3 不兼容,后者不再知道 long 类型,并且不包括基于库的数字类型,例如 numpy.int32.

您列出的那些类型实际上有一个基础 class。

如果你不看 numpy 类型,一个好的起点是 numbers.Complex:

>>> import numbers
>>> isinstance(1+9j, numbers.Complex)
True
>>> isinstance(1L, numbers.Complex)
True
>>> isinstance(1., numbers.Complex)
True
>>> isinstance(1, numbers.Complex)
True

当你开始包含来自 numpy 的那些时,它会变得有点混乱,但是,numbers.Complex 抽象基础 class 已经处理了大量提到的情况。

抱歉,聚会有点晚了。但这可能对本页的未来读者有所帮助。我建议您使用 Python 的“鸭子打字”字符及其 EAFP(“请求宽恕比许可更容易”)理念:换句话说,只需尝试将所讨论的对象用作数字即可。像这样写:

def isnumber(thing):
    try:
        thing + 0
        return True
    except TypeError:
        return False

它应该适用于任何类型的数字,包括用户定义的 类。