Как правильно использовать isinstance () python, чтобы проверить, является ли переменная числом?

я нашел старый код Python, который делал что-то вроде:

if type(var) is type(1):
   ...

как и ожидалось,pep8 жалуется на это, рекомендуя использовать isinstance().

теперь проблема в том, что numbers модуль был добавлен в Python 2.6 и мне нужно написать код, который работает с Python 2.5+

так if isinstance(var, Numbers.number) это не решение.

какое решение было бы правильным в этом случае?

3 ответов


в Python 2, Вы можете использовать types модуль:

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

обратите внимание на использование кортежа для тестирования против нескольких типов.

под капотом IntType - это просто псевдоним для int, etc.:

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

на complex type требует, чтобы ваш python был скомпилирован с поддержкой комплексных чисел; если вы хотите защитить это, используйте блок try/except:

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

или если вы просто использовать типы напрямую:

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

В Python 3 types больше не имеет стандартных псевдонимов типа,complex всегда включен, и больше нет long vs int разница, поэтому в Python 3 Всегда используйте:

NumberTypes = (int, float, complex)

последнее, но не менее, вы можете использовать numbers.Numbers абстрактный базовый тип (новый в Python 2.6) также поддерживает пользовательские числовые типы, которые не являются производными непосредственно от вышеуказанных типов:

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

эта проверка также возвращает True для decimal.Decimal() и fractions.Fraction() объекты.

этот модуль делает предположение, что complex тип включен; вы получите ошибку импорта, если это не так.


Python 2 поддерживает четыре типа чисел int,float, long и complexи python 3.x поддержка 3:int, float и complex

>>> num = 10
>>> if isinstance(num, (int, float, long, complex)): #use tuple if checking against multiple types
      print('yes it is a number')

yes it is a number
>>> isinstance(num, float)   
False
>>> isinstance(num, int)
True
>>> a = complex(1, 2)
>>> isinstance(a, complex)
True

в зависимости от того, что вы используете это в утиной типизацией может быть лучший подход (это конечно обычно рекомендовано). Проблема с подходом Martijn Pieters заключается в том, что вы всегда будете пропускать некоторые типы чисел из своего списка. С моей головы ваш код не будет работать с: симпатичными рациональными числами, произвольными целыми числами точности и любой реализацией комплексных чисел.

один из вариантов-написать функция такова:

def is_number(thing):
    try:
        thing + 1
        return True
    except TypeError:
        return False

этот код должен работать с любой разумной реализации. Конечно, есть большой недостаток: он также будет работать с необоснованной реализацией множества не-чисел (т. е. если оператор plus перегружен и принимает целое число).

Другой альтернативой (в зависимости от того, почему вам нужно знать, является ли что-то числом), является просто предположить, что это число, и если это не ошибки, будут брошены любым битом код требует номера.

Я не говорю, что эти подходы всегда лучше (в отличие от некоторых людей... только то, что они заслуживают рассмотрения.