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?
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.