一致的数字类型检查

时间:2014-03-28 19:35:41

标签: python python-2.7 numpy types numbers

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

为了说清楚,我正在使用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继承而来:< / p>

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)

我将为您提供全部输出,但有一些摘录:

    type 'int'
    Is an int: True
    Is a float: False
    Is a complex: False
    Is a numbers.Number: True
    Is an numbers.Integer: True
    Is a numbers.Real: True
    Is a numbers.Complex: True
    Is a numpy.integer: False
    Is a numpy.floating: False
    Is a numpy.complex: False

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

    type 'numpy.int64'
    Is an int: True
    Is a float: False
    Is a complex: False
    Is a numbers.Number: True
    Is an numbers.Integer: True
    Is a numbers.Real: True
    Is a numbers.Complex: True
    Is a numpy.integer: True
    Is a numpy.floating: False
    Is a numpy.complex: False

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

    type 'numpy.int16'
    Is an int: False
    Is a float: False
    Is a complex: False
    Is a numbers.Number: False
    Is an numbers.Integer: False
    Is a numbers.Real: False
    Is a numbers.Complex: False
    Is a numpy.integer: True
    Is a numpy.floating: False
    Is a numpy.complex: False

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

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

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

1 个答案:

答案 0 :(得分:5)

数字中的类是抽象基类,你可以将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进行计算,可能会发生溢出。