简体   繁体   中英

Best way to check if a variable is a number (int, float, np.float32, np.int64, ...) in python?

I am running in this multiple times now and never found a satisfying solution.

I want to check: Is variable some_var of a number type?
More specific for me: Can it be compared to another number? (eg a string should fail)

Numpy makes this somehow difficult since:

some_var = np.int32(123)
isinstance(some_var, int)
>>> False

Possible Solutions

numpy solutions: np.issubtype , comparison to np.number , np.isscalar

I found np.issubtype as workaround, but this will fail for non-numpy types:

some_var = 123
np.issubdtype(some_var.dtype, np.number)
>>> AttributeError: 'int' object has no attribute 'dtype'

np.number can be used for comparison, but also fails for non-numpy types

isinstance(1, np.number)
>>> False

np.isscalar() works fine, but also allows strings:

np.isscalar('test')
>>>True

numbers module

There is the comparison with the numbers module . Which seems to work convenient, but needs an extra import. So far probably the best solution.

from numbers import Integral

isinstance(some_var, Integral)
>>> True

Manual testing

The clearest way of course would be a manual test.

isinstance(some_var, (int, float, np.int32, np.int64, np.float32, np.float64))
>>> True

My Questions

Am I missing a way?
What would be the most recommended?

As the short answer did not catch the audience, here the extended answer: There is no generic function to check against every numeric type in existance, as every package can implement their own.

It is also advisable, to control, which variable types to accept, as packages can have different implementation behaviour (eg integer division 1 / 10 = 0.1 or 1 / 10 = 0 .

Therefore a simple isNumeric check is advisable.

Now two versions come to my mind:

NUMERIC_TYPES = [int, float, ...] #to be extended by acceptable types
def isNumeric(val):
    return isinstance(val, NUMERIC_TYPES)

however there is a more performant version (my laptop 15%)

NUMERIC_TYPES = set((int, float, np.int32, np.int64, np.float32, np.float64,...))

def isNumeric(val):
    return type(val) in NUMERIC_TYPES

And for @CodePrinz isinstance and type(x)== is not the same!

class StupidInt(int):
    def __init__(self, val):
        self._privateInt = val
    def __add__(self, other):
        return self._privateInt - other

a = StupidInt(10)
b = StupidInt(10)
print("a + b = 0? whaaat?")
print(a+b)

print("isInstance: {}".format(isinstance(a, int)))
print("is of type: {}".format(type(a) == int))
----
a + b = 0? whaaat?
0
isInstance: True
is of type: False

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM