Подтвердить что ты не робот

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

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

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

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

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

Итак, if isinstance(var, Numbers.number) не является решением.

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

4b9b3361

Ответ 1

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

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

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

Под капотом IntType является просто псевдонимом для int и т.д.:

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

Тип complex требует, чтобы ваш 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)
...

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

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

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

Ответ 2

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

Ответ 3

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

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

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

Этот код должен работать с любой разумной реализацией числа. Конечно, есть существенный недостаток: он также будет работать с необоснованной реализацией множества не чисел (т.е. Если оператор плюс перегружен и принимает целое число).

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

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