Узнаем тип числа: int, float, complex

Раздел: Типы данных -> Проверка типа

Основные способы проверки типа числа в Python

Python поддерживает три встроенных числовых типа: int (целое), float (вещественное) и complex (комплексное). При работе с данными часто требуется определить, к какому из этих типов относится переменная. Ниже рассмотрены основные методы проверки, их сильные стороны и возможные подводные камни.

Как наиболее эффективно проверить тип числа с учётом наследования?

Лучший способ - функция isinstance(). Она учитывает иерархию классов (например, bool является подклассом int). Пример:

x = 10
print(isinstance(x, int))  # True
print(isinstance(x, float)) # False
print(isinstance(x, (int, float, complex))) # True

тип числа python (тип числа в python)

Пояснение: isinstance(x, int) вернёт True для целых чисел и для булевых значений (True, False), так как bool унаследован от int. Если нужно проверить принадлежность сразу к нескольким типам, передаётся кортеж типов.

Проблема: isinstance(True, int) даёт True. Это может быть неожиданно, если требуется отличить именно целое число от логического. Решение - дополнительно проверить, не является ли значение булевым: type(x) is not bool and isinstance(x, int).

Как проверить точное соответствие типу без учёта наследования?

Используйте type() и сравнение с типом через is или ==:

x = 3.14
print(type(x) is float)  # True
print(type(x) == int)    # False
print(type(True) is int) # False (так как type(True) - bool)

Пояснение: type(x) возвращает класс объекта. Сравнение is предпочтительнее, так как он быстрее и гарантирует точное совпадение. Этот метод не считает bool за int.

Проблема: не работает для проверки нескольких типов. Придётся писать type(x) is int or type(x) is float. Альтернатива - type(x) in (int, float, complex).

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

Модуль numbers содержит абстрактные базовые классы. Например, numbers.Number охватывает все встроенные числовые типы и пользовательские, зарегистрированные как числовые:

import numbers
x = 42
print(isinstance(x, numbers.Number))         # True
print(isinstance(2+3j, numbers.Complex))     # True
print(isinstance(3.14, numbers.Real))        # True
print(isinstance(5, numbers.Integral))       # True

Пояснение: numbers.Number - верхний уровень. Для более точной проверки используйте numbers.Complex, numbers.Real, numbers.Integral. Этот подход полезен, когда код должен работать не только со стандартными типами, но и с Decimal, Fraction и т.д.

Проблема: модуль numbers не входит в ядро языка и может быть неочевиден для новичков. Также isinstance(True, numbers.Integral) вернёт True.

Расширенные примеры проверки типа числа

Ниже приведены дополнительные сценарии и кейсы, которые помогут глубже понять особенности определения числовых типов.

Пример 1: поведение bool при проверке типа

Пример
# bool - подкласс int
flag = True
print(type(flag))           # <class 'bool'>
print(isinstance(flag, int)) # True (опасно)
# как отличить?
print(type(flag) is int)    # False
print(isinstance(flag, int) and type(flag) is not bool)  # False
<class 'bool'>
True
False
False

Пояснение: если требуется исключить булевы значения, нужно явно проверять, что тип не bool.

Пример 2: проверка комплексных чисел

Пример
c = 1 + 2j
print(isinstance(c, complex))          # True
print(isinstance(c, numbers.Complex))  # True
print(type(c) is complex)              # True
# Но комплексное число не является вещественным
print(isinstance(c, numbers.Real))     # False
True
True
True
False

Пояснение: complex - отдельный тип. Проверка через numbers.Complex полезна для обобщённого кода.

Пример 3: проверка на целое число без плавающей точки (float, представляющий целое)

Пример
# float может хранить целые значения, но тип остаётся float
y = 5.0
print(type(y) is float)       # True
print(isinstance(y, int))     # False (так как это float)
# метод is_integer() позволяет проверить, является ли float целым числом
print(y.is_integer())         # True
z = 5.5
print(z.is_integer())         # False
True
False
True
False

Пояснение: float.is_integer() возвращает True, если дробная часть равна нулю. Это не проверка типа, но полезно при работе с вещественными числами.

Пример 4: проверка NaN и Infinity

Пример
import math
nan = float('nan')
inf = float('inf')
print(type(nan) is float)   # True
print(math.isnan(nan))      # True
print(math.isinf(inf))      # True
# isinstance не различает специальные значения
print(isinstance(nan, float))  # True
True
True
True
True

Пояснение: NaN и Infinity - это допустимые значения float, поэтому проверка типа вернёт float, но для их обнаружения нужны специальные функции.

Пример 5: использование numbers.Number для проверки произвольного числа

Пример
import numbers
from decimal import Decimal
from fractions import Fraction

d = Decimal('10.5')
f = Fraction(3, 4)

print(isinstance(d, numbers.Number))  # True
print(isinstance(f, numbers.Number))  # True
print(isinstance(d, numbers.Real))    # True (Decimal считается Real)
print(isinstance(f, numbers.Real))    # True
True
True
True
True

Пояснение: абстрактные классы numbers охватывают не только встроенные типы, но и популярные расширения, что делает код более универсальным.

Пример 6: типичные ошибки при проверке типа

Пример
# Ошибка: сравнение с строкой вместо типа
x = 10
# Неправильно: if type(x) == "int":  # всегда False
# Правильно: if type(x) is int:

# Ошибка: забыть про bool
if isinstance(False, int):  # True, хотя False - не число с точки зрения логики
    print("bool считается int")  # сработает

# Ошибка: путаница между type() и isinstance() при проверке наследования
# type() не учитывает подклассы, isinstance() учитывает.
bool считается int

Пояснение: эти подводные камни часто приводят к багам, особенно при обработке логических флагов вместе с числами.

Тип числа в Python - comments

En
тип числа python (python)