Python: уроки, справочник и задачи

Python isinstance: как проверить тип переменной

Раздел: Функции Python · Обновлено 31.10.2026

Функция isinstance в Python проверяет, является ли объект экземпляром указанного класса или его наследника, и возвращает True или False. С ее помощью функции обрабатывают аргументы разных типов, валидируют входные данные и разбирают JSON. В статье показан синтаксис, проверка сразу нескольких типов, разница с type(), работа с абстрактными классами и типичные ошибки.

python isinstance
Фото: CEphoto, Uwe Aranas / CC BY-SA 3.0, Wikimedia Commons
Содержание статьи
  1. Синтаксис и параметры
  2. Проверка нескольких типов
  3. Наследование и иерархия классов
    1. Ловушка с bool и int
  4. isinstance() или type()
  5. Проверка по абстрактным классам
  6. Где isinstance() используют на практике
  7. Частые вопросы
    1. Как проверить, что переменная - число?
    2. Как проверить, что значение равно None?
    3. Можно ли передать список классов вместо кортежа?
    4. Работает ли isinstance() с подсказками вроде list[int]?

Синтаксис и параметры

Функция встроенная, импорт не нужен. Она принимает ровно два позиционных аргумента.

isinstance(obj, classinfo)

Результат True, если объект относится к указанному классу или к любому классу, унаследованному от него. Если второй аргумент не является классом, Python выбросит TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union.

numbers = [1, 2, 3]
print(isinstance(numbers, list))   # True
print(isinstance(numbers, dict))   # False
print(isinstance("5", int))        # False - это строка
print(isinstance(5.0, float))      # True

Перечень встроенных классов, которые чаще всего подставляют во второй аргумент, есть в статье типы данных в Python.

Проверка нескольких типов

Чтобы проверить принадлежность к одному из нескольких классов, передайте их кортежем. Достаточно совпадения с любым элементом, это аналог цепочки or.

def describe(value):
    if isinstance(value, (int, float)):
        return f"число {value}"
    if isinstance(value, (list, tuple, set)):
        return f"коллекция из {len(value)} элементов"
    return f"другое: {type(value).__name__}"

print(describe(3.5))       # число 3.5
print(describe((1, 2)))    # коллекция из 2 элементов
print(describe("текст"))   # другое: str

В Python 3.10 и новее вместо кортежа можно написать объединение isinstance(value, int | float). Результат тот же, а запись совпадает с синтаксисом аннотаций типов. Кортежи допускаются вложенными: (int, (list, tuple)) тоже сработает.

Наследование и иерархия классов

Главное отличие isinstance() от сравнения типов в том, что она учитывает наследование. Объект дочернего класса считается экземпляром и родителя, и всех классов выше по иерархии, вплоть до object.

class Animal:
    pass

class Dog(Animal):
    pass

rex = Dog()
print(isinstance(rex, Dog))     # True
print(isinstance(rex, Animal))  # True - Dog наследует Animal
print(isinstance(rex, object))  # True - любой объект
print(isinstance(Animal(), Dog))  # False

Это позволяет писать код для базового класса, и он автоматически будет работать со всеми наследниками. Как строятся такие иерархии, описано в статье наследование классов.

Ловушка с bool и int

В Python тип bool унаследован от int, поэтому True и False проходят проверку на целое число. В функциях, которые должны принимать только числа, это приводит к незаметным ошибкам.

print(isinstance(True, int))  # True

def set_count(n):
    if isinstance(n, bool) or not isinstance(n, int):
        raise TypeError("нужно целое число")
    return n

set_count(10)    # 10
# set_count(True) -> TypeError

isinstance() или type()

Сравнение type(x) == list или type(x) is list проверяет точное совпадение класса и не учитывает наследников. В большинстве задач это скорее недостаток, поэтому для проверок рекомендуют isinstance().

ПроверкаУчитывает наследованиеНесколько типовКогда применять
isinstance(x, cls)дакортеж или |обычная проверка аргументов
type(x) is clsнеттолько через inнужен строго конкретный класс
issubclass(A, B)дакортеж или |сравнение классов, а не объектов
from collections import OrderedDict

d = OrderedDict(a=1)
print(isinstance(d, dict))  # True
print(type(d) is dict)      # False - класс OrderedDict
print(issubclass(OrderedDict, dict))  # True

issubclass() принимает первым аргументом класс, а не объект. Вызов issubclass(d, dict) закончится ошибкой TypeError.

Проверка по абстрактным классам

Иногда важен не конкретный тип, а поведение: можно ли перебрать объект циклом, поддерживает ли он обращение по ключу. Для этого во втором аргументе указывают абстрактные классы из модуля collections.abc или numbers.

from collections.abc import Iterable, Mapping
from numbers import Number

print(isinstance([1, 2], Iterable))   # True
print(isinstance("abc", Iterable))    # True - строка тоже перебирается
print(isinstance({"a": 1}, Mapping))  # True
print(isinstance(3 + 2j, Number))     # True - комплексное число

Так функция примет любой подходящий объект, включая пользовательские классы, без перечисления всех вариантов. Обратите внимание, что строка тоже итерируемая: если нужно отличить список от строки, проверяйте str отдельно и раньше.

Где isinstance() используют на практике

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

def count_leaves(data):
    if isinstance(data, dict):
        return sum(count_leaves(v) for v in data.values())
    if isinstance(data, list):
        return sum(count_leaves(v) for v in data)
    return 1

print(count_leaves({"a": [1, 2], "b": {"c": 3}}))  # 3

Не стоит злоупотреблять проверками: если функция просто вызывает у объекта метод, обычно проще его вызвать и обработать возможную ошибку. Для разбора данных по структуре с Python 3.10 есть оператор match case, который делает те же проверки типов короче. А статический контроль типов до запуска программы обеспечивают аннотации типов и анализаторы вроде mypy. Описание функции приведено в документации Python.

Частые вопросы

Короткие ответы на вопросы о проверке типов через isinstance().

Как проверить, что переменная - число?

Для целых и дробных подойдет isinstance(x, (int, float)), для любых числовых типов, включая Decimal и complex, используйте numbers.Number. Не забудьте исключить bool, если он не нужен.

Как проверить, что значение равно None?

Не через isinstance(), а сравнением x is None. Это короче и считается стандартной записью.

Можно ли передать список классов вместо кортежа?

Нет. Второй аргумент должен быть классом, кортежем или объединением через |. Список вызовет TypeError, его нужно преобразовать: tuple(types).

Работает ли isinstance() с подсказками вроде list[int]?

Нет. Обобщенные типы с параметрами не поддерживаются, isinstance(x, list[int]) выдаст TypeError. Проверяйте сам контейнер, а элементы отдельно, например через all().