2

When working with integers there are multiple types available (e.g. int, numpy.int8, numpy.int16, etc.). If I write a generic function that requires one variable to be an integer how can I test the type against all possible "integer" types within Python/numpy? The same can be asked about floats. I initially thought this

isinstance(np.int64(5), int)

would/should work, but it doesn't.

Is there a way I can test an integer variable for all available integer types?

a_guest
  • 34,165
  • 12
  • 64
  • 118
tnknepp
  • 5,888
  • 6
  • 43
  • 57
  • Not really. You can only create a tuple of the int types manually and use it as second argument for "isinstance". – Michael Butscher Feb 19 '21 at 19:40
  • @MichaelButscher That's what I thought. I was just hoping for something a little more elegant. But, if it works... – tnknepp Feb 19 '21 at 19:42

2 Answers2

6

You can use numbers.Integral and numbers.Real respectively:

from numbers import Integral, Real

isinstance(x, Integral)
isinstance(x, Real)
a_guest
  • 34,165
  • 12
  • 64
  • 118
  • Real doesn't provide the same kind of test as Integral does, it just tests whether x is real or not. While isinstance(np.int64(x), Integral) returns True, so does isinstance(np.int64, Real)...so it's not testing for a float type. – tnknepp Feb 22 '21 at 16:01
  • @tnknepp `isinstance` doesn't check for type identity, it checks whether the given object is compatible with the given type(s). This includes abstract base classes which form the numeric tower as defined in the `numbers` module. That's also how static type checkers handle the situation (i.e. `x: float = 1` passes). If that's not what you want, then you need to provide the exact list of (concrete) types to check. But if you already know that `isinstance(x, Integral)` why would you check `isinstance(x, Real)`? – a_guest Feb 22 '21 at 17:12
  • I was confused about why you included the Real example. I tangentially mentioned floats in the original post so I thought you were suggesting Real could be used to test for a float, which made no sense at all. I get it now. Is there a similar test for floats? – tnknepp Feb 22 '21 at 17:52
  • @tnknepp Perhaps I'm not fully understanding what you mean. `Real` tests for *compatibility* with float, i.e. if `isinstance(x, Real)` then `float(x)` will succeed. If you only need to distinguish between two data types, int and float, then testing for `Integral` is sufficient. If you want to distinguish complex numbers as well, then you'd need an additional test for `Real`. What do you want to test in the end? – a_guest Feb 22 '21 at 19:51
  • This is getting off topic from the original question (my fault). I was just wondering if there is a way to determine if something is a float and nothing else. Real will return true for a float and integer, so it's not exclusive. That said, I think I have all the information I need. – tnknepp Feb 22 '21 at 20:06
5

In Python there is only a single int type. If you want to test all integer types in numpy, plus the built-in int type, you can use:

isinstance(x, (int, np.integer))

Where np.integer is an abstract base class of all scalar numpy integer types. Similarly for float,

isinstance(x, (float, np.floating))
juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172