2014-03-28 64 views
4

讓我們把鴨子留在池塘裏。爲了說清楚,我正在使用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本身(int有些矛盾, floatcomplex剛剛從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) 

饒你全力輸出,但一些摘錄:

 
    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模塊,而是做以下?

類型檢查:在數字

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

回答

5

類是抽象基類,你可以註冊numpy.int *爲積分:

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

但numpy.int16的範圍是小於int,如果使用numpy.int16進行計算,則可能發生溢出。

+0

我不知道寄存器功能非常方便。 「數字」類的MRO仍然很古怪。從數學的角度來看,我可以看到一個整數可能是一個特定的理性,真實或複雜的數字,但是從編程方面來說,MRO似乎是無益的。所以從本質上講,如果我想檢查一個數字的類型,我首先必須檢查複雜的,然後是真實的,然後是理性的,最後是整數。 – Midnighter