Python: how to check a variable is a meaningful numerical type
<p>In python, how can I check a variable is a numerical type and has a meaningful value? </p>

<p>Here I mean by 'numerical type' those like <code>int</code>, <code>float</code>, and <code>complex</code> with all different bit length, and by 'meaningful value' that it is not <code>nan</code> or any other special values that can not be used for further computation. </p>

<p>(I guess this is such a common issue and there must be a duplicate question, but I did not find one after a quick search. Please let me know if there is a duplicate.)</p>

<p>It depends how thorough you want to be. Besides the builtin types (<code>complex</code>, <code>float</code>, and <code>int</code>) there are also other types that are considered numbers in python. For instance: <a href="https://docs.python.org/3/library/fractions.html" rel="nofollow"><code>fractions.Fraction</code></a>, <a href="https://docs.python.org/3/library/decimal.html" rel="nofollow"><code>decimal.Decimal</code></a>, and even <code>bool</code> can act as a number. Then you get external libraries that have their own numeric types. By far the biggest is <a href="http://www.numpy.org/" rel="nofollow"><code>numpy</code></a>. With <code>numpy</code> some of its types will succeed <code>isinstance</code> checks, and other will not. For instance: <code>isinstance(numpy.float64(10), float)</code> is true, but <code>isinstance(numpy.float32(10), float)</code> is not.
On top of all this you could even have a user defined class that acts like a number.</p>

<p>Python does provide one way of getting around this -- the <a href="https://docs.python.org/3/library/numbers.html" rel="nofollow"><code>numbers</code></a> module. It provides several abstract types that represent different types of numbers. Any class that implements numeric functionality can register itself as being compatible with the relevant types. <code>numbers.Number</code> is the most basic, and therefore the one you're looking for. All you have to do is use it  in your <code>isinstance</code> checks. eg.</p>

<pre><code>from numbers import Number
from decimal import Decimal
from fractions import Fraction
import numpy

assert isinstance(1, Number)
assert isinstance(1.5, Number)  
assert isinstance(1+5j, Number)  
assert isinstance(True, Number)

assert isinstance(Decimal("1.23"), Number)
assert isinstance(Fraction(1, 2), Number)

assert isinstance(numpy.float64(10), Number)
assert isinstance(numpy.float32(10), Number)
assert isinstance(numpy.int32(10), Number)
assert isinstance(numpy.uint32(10), Number)
</code></pre>

<p>That still leaves us with the problem about whether the object is actually a number, rather than "not a number". The <a href="https://docs.python.org/3/library/math.html#math.isnan" rel="nofollow"><code>math.isnan</code></a> function is good for this, but it requires that the number be convertible to a float (which not all numbers are). The big problem here is the <code>complex</code> type. There are a few ways around this: additional <code>isinstance</code> checks (but that comes with its own headaches), using <a href="https://docs.python.org/3/library/functions.html#abs" rel="nofollow"><code>abs</code></a>, or testing for equality.</p>

<p><code>abs</code> can be used on every numeric type (that I can think of). For most numbers it returns the positive version of the number, but for complex numbers it returns its magnitude (a float). So now we can do  that <code>isnan</code> check. <code>nan</code> is also a special number in that it is the only number that is not equal to itself.</p>

<p>This means your final check might look like:</p>

<pre><code>import math
import numbers

def number_is_not_nan(n):
    return isinstance(n, numbers.Number) and not math.isnan(abs(n))

def number_is_finite(n):
    return isinstance(n, numbers.Number) and not math.isfinite(abs(n))
</code></pre>

python numpy math