How to properly use python's isinstance() to check if a variable is a number?

pep8, python, python-2.5

Solution

In Python 2, you can use the `types` module:

>>> import types
>>> var = 1
>>> NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType)
>>> isinstance(var, NumberTypes)
True

Note the use of a tuple to test against multiple types.

Under the hood, `IntType` is just an alias for `int`, etc.:

>>> isinstance(var, (int, long, float, complex))
True

The `complex` type requires that your python was compiled with support for complex numbers; if you want to guard for this use a try/except block:

>>> try:
...     NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType)
... except AttributeError:
...     # No support for complex numbers compiled
...     NumberTypes = (types.IntType, types.LongType, types.FloatType)
...

or if you just use the types directly:

>>> try:
...     NumberTypes = (int, long, float, complex)
... except NameError:
...     # No support for complex numbers compiled
...     NumberTypes = (int, long, float)
...

In Python 3 `types` no longer has any standard type aliases, `complex` is always enabled and there is no longer a `long` vs `int` difference, so in Python 3 always use:

NumberTypes = (int, float, complex)

Last but not least, you can use the `numbers.Numbers` abstract base type (new in Python 2.6) to also support custom numeric types that don't derive directly from the above types:

>>> import numbers
>>> isinstance(var, numbers.Number)
True

This check also returns `True` for `decimal.Decimal()` and `fractions.Fraction()` objects.

This module does make the assumption that the `complex` type is enabled; you'll get an import error if it is not.

Problem

I found some old Python code that was doing something like: ``` if type(var) is type(1): ... ``` As expected, `pep8` complains about this recommending usage of `isinstance()`. Now, the problem is that the `numbers` module was added in Python 2.6 and I need to write code that works with Python 2.5+ So `if isinstance(var, Numbers.number)` is not a solution. Which would be the proper solution in this case?

Original source

Related problems