【问题标题】:Consistent numeric type check一致的数字类型检查
【发布时间】:2014-03-28 19:35:41
【问题描述】:

让我们把鸭子留在池塘里。

为了清楚起见,我正在使用 Python 2.7.3。

我在玩数字检查时遇到了一些我觉得奇怪的事情:

In [1]: numbers.Number.mro()
Out[1]: [numbers.Number, object]

In [2]: numbers.Complex.mro()
Out[2]: [numbers.Complex, numbers.Number, object]

In [3]: numbers.Real.mro()
Out[3]: [numbers.Real, numbers.Complex, numbers.Number, object]

In [4]: numbers.Rational.mro()
Out[4]: [numbers.Rational, numbers.Real, numbers.Complex,
         numbers.Number, object]

In [5]: numbers.Integral.mro()
Out[5]: [numbers.Integral, numbers.Rational, numbers.Real,
         numbers.Complex, numbers.Number, object]

这让我觉得...适得其反,并且在 Python 本身内部有些矛盾(intfloatcomplex 直接继承自 object):

In [6]: isinstance(int(), complex)
Out[6]: False

In [7]: isinstance(int(), numbers.Complex)
Out[7]: True

然后我写了以下函数:

def numeric_check(num):
    print "Is an int:", isinstance(num, int)
    print "Is a float:", isinstance(num, float)
    print "Is a complex:", isinstance(num, complex)
    print "Is a numbers.Number:", isinstance(num, numbers.Number)
    print "Is an numbers.Integer:", isinstance(num, numbers.Integral)
    print "Is a numbers.Real:", isinstance(num, numbers.Real)
    print "Is a numbers.Complex:", isinstance(num, numbers.Complex)
    print "Is a numpy.integer:", isinstance(num, numpy.integer)
    print "Is a numpy.floating:", isinstance(num, numpy.floating)
    print "Is a numpy.complex:", isinstance(num, numpy.complex)

并运行以下循环:

for dtype in [int, float, complex,
              numpy.int16, numpy.int32, numpy.int64,
              numpy.uint16, numpy.uint32, numpy.uint64,
              numpy.float16, numpy.float32, numpy.float64, numpy.complex64]:
    num = dtype()
    print dtype
    numeric_check(num)

我会给你完整的输出,但摘录一些:

输入'int' 是一个整数:真 是否为浮点数:False 是一个复杂的:假 是一个数字。数字:真 是一个数字。整数:真 是数字。实数:真 是一个数字。复数:真 是一个 numpy.integer: False 是一个 numpy.floating: False 是一个 numpy.complex: False

从上面可以看出,intnumbers 模块中任何类型的实例。在我的机器上默认的numpy整数是64bit,我们来看看:

输入“numpy.int64” 是一个整数:真 是否为浮点数:False 是一个复杂的:假 是一个数字。数字:真 是一个数字。整数:真 是数字。实数:真 是一个数字。复数:真 是 numpy.integer: True 是一个 numpy.floating: False 是一个 numpy.complex: False

它匹配与int 相同的类型,另外作为numpy.integer 传递。让我们检查一下numpy.int16

输入“numpy.int16” 是一个整数:假 是否为浮点数:False 是一个复杂的:假 是一个数字。数字:假 是一个数字。整数:假 是数字。实数:假 是一个数字。复数:假 是 numpy.integer: True 是一个 numpy.floating: False 是一个 numpy.complex: False

哎呀,它只作为numpy.integer 传递。所以我的问题:

  1. 这是斯巴达吗?
  2. numpy 部分的类型分离是设计选择吗?
  3. 抛开打字不谈,如果我想检查数字类型,我最好忽略numbers 模块,而是执行以下操作?

类型检查:

isinstance(num, (int, numpy.integer)
isinstance(num, (float, numpy.floating)
isinstance(num, (complex, numpy.complex)

【问题讨论】:

    标签: python python-2.7 numpy types numbers


    【解决方案1】:

    数字中的类是抽象基类,您可以将 numpy.int* 注册为 Integral:

    import numpy as np
    import numbers
    numbers.Integral.register(numpy.integer)
    a = np.int16(100)
    isinstance(a, numbers.Integral)
    

    但是numpy.int16的范围比int小,如果用numpy.int16计算,可能会溢出。

    【讨论】:

    • 我不知道非常方便的注册功能。 numbers 类的 MRO 仍然看起来很奇怪。从数学的角度来看,我可以看到整数可能是特定的有理数、实数或复数,但从编程方面来看,MRO 似乎没有帮助。所以本质上,如果我想检查数字的类型,我首先必须检查复数,然后是实数,然后是有理数,最后是整数。
    猜你喜欢
    • 2021-10-13
    • 1970-01-01
    • 2018-05-18
    • 2016-03-10
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多