Функция isinstance() в Python: как и зачем проверять типы данных

Руководство с примерами — только основное об этой функции

Функция isinstance() в Python: как и зачем проверять типы данных

Разбираем ещё один встроенный инструмент в языке программирования Python: функцию isinstance. Это простой пример, на котором можно посмотреть на некоторые задачи разработки и на их решения.

Хотя isinstance — несложная функция, но, если рассказывать обо всём в деталях, одной статьи не хватит. Так что сегодня выбираем самое основное и интересное.

Что делает функция isinstance() в Python

Разные элементы программы имеют разные типы: строки, числа, списки, словари. Функция isinstance в Python проверяет, относится ли указанный объект к определённому типу или нет. 

Основное назначение и принцип работы

Применяя isinstance, мы уточняем: «Этот объект — число? Кортеж? Булева переменная?» А программа проверяет и отвечает «да» или «нет». 

Вот как это выглядит в коде:

# проверяем, что переменная a — это число
a = 777
# если это int, isinstance вернёт True
print(isinstance(a, int))

Запускаем код и получаем результат проверки:

True

# создаём классы
class King: pass
class Prince(King): pass

# создаём объект
kid = Prince()

# type() сравнивает строго
print("Результат работы type(): ", type(kid) == King)
# isinstance() учитывает наследование
print("Результат работы isinstance(): ", isinstance(kid, King))

Теперь запускаем код и получаем такой результат:

Результат работы type(): False
Результат работы isinstance(): True

Здесь видно первое различие двух функций: isinstance()отслеживает наследование, то есть проверяет аргумент в скобках на принадлежность к родительскому классу. У type() получается строгая проверка, потому что он не видит связи наследований.

Если объяснять чуть сложнее, то type() — это вообще не функция, а ещё один класс.

Например, мы создаём целое число:

x = 5

Узнаём его тип через type():

print(type(x))

Получаем такое:

<class 'int'>

Но теперь сюрприз: тип можно проверить и у самого int, потому что в Python все элементы являются объектами со своими типами:

print(type(int))

Получаем, что это объект класса 'type':

<class 'type'>

Крутая особенность этого инструмента в том, что помощью type() можно создать новый класс одной строкой. Например, пустой класс без описания можно объявить так:

class Hero:
pass

А можно написать так:

Hero = type('Hero', (), {})

У этого способа свой синтаксис, который мы разберём в отдельной статье. А сегодня — только про isinstance(), чтобы не путаться.

Первая IT-работа: 30 откликов — тишина. Знакомо?

Карьерный навигатор Практикума разберёт ваше резюме, проложит маршрут к первому работодателю, подготовит к собеседованиям в 2026 году, а с января начнёт подбирать вакансии именно под вас.

Бесплатно до 15 января!

Синтаксис функции isinstance()

Для работы нужна сама функция и два аргумента. Смотрим на нескольких примерах.

Правильная запись и параметры

Чтобы проверить тип объекта, мы пишем ключевое слово isinstance() и передаём в скобках два параметра-аргумента: первый — это наш объект, а второй — тип, на соответствие которому мы его проверяем.

Получается так:

isinstance(object, classinfo)

Здесь object — это объект, а classinfo — тип данных.

Попробуем на примере со строкой:

# проверяем, что name — это строка
name = "Bilbo Baggins"
print(isinstance(name, str))

Запускаем эту небольшую программу и в консоли видим результат:

True

Возвращаемое значение

Функция всегда возвращает True или False, потому сам принцип её работы — дать однозначный ответ. 

Но этот ответ можно обернуть в другой код и немного усложнить. Например, сделать развилку в программе: при положительном ответе запускать один фрагмент кода, при отрицательном — другой:

# проверяем тип перед действием
specified = "Многие читали «Хоббита» — многие, да не все"

if isinstance(specified, str):
   print("Это текст")
else:
   print("Это не текст")

Проверяем, что получается в консоли:

Это текст

Какие типы данных можно проверять

Isinstance() работает со всеми стандартными типами данных в Python, пользовательскими классами и кортежами из нескольких классов.

Можно перебрать список объектов разного типа. Например, если нужно найти все числа, мы создаём цикл и проверяем все элементы на соответствие типам данных int и float. Обратите внимание, что в скобках мы передаём два аргумента через запятую:

# проверяем разные типы
checks = [0, "Ring", 1.379, {"Elves": 3, "Gnomes": 7, "Human": 9}]

for checking in checks:
   if isinstance(checking, (int, float)):
       print(f"{checking} — это число")

При запуске Питон находит все целые числа и числа с плавающей точкой:

0 — это число
1.379 — это число

Полезный блок со скидкой

Если вам интересно разбираться со смартфонами, компьютерами и прочими гаджетами и вы хотите научиться создавать софт под них с нуля или тестировать то, что сделали другие, — держите промокод Практикума на любой платный курс: KOD (можно просто на него нажать). Он даст скидку при покупке и позволит сэкономить на обучении.

Бесплатные курсы в Практикуме тоже есть — по всем специальностям и направлениям, начать можно в любой момент, карту привязывать не нужно, если что.

Примеры использования isinstance()

Для лучшего закрепления разберём ещё несколько примеров.

Проверка базовых типов данных

При работе со встроенными типами данных мы передаём в isinstance() объект-переменную и сравниваем его с нужным типом данных. В примере ниже мы проверяем объект на соответствие целому числу:

# пользовательский ввод
built = "33"

# проверяем, число ли это
if isinstance(built, int):
   print("Это число, с ним можно выполнять математические операции")
else:
   print("Это не число, сначала нужно преобразовать")

Смотрим, что получается на выходе:

Это не число, сначала нужно преобразовать

Фокус в том, что в переменную мы передаём строку — но её можно преобразовать в число и работать с ним. Поэтому так можно отследить неправильный тип данных в местах, где нужны дополнительные операции.

Работа с пользовательскими классами

Можно проверять, относится ли объект к нужному классу, чтобы применять правильные методы. Например, определить в игре персонажа на принадлежность к союзникам или врагам и настроить подходящее поведение.

При создании класса его можно унаследовать от другого класса — тогда унаследованный класс получает все возможности родительского. Важная особенность isinstance() в том, что функция отслеживает эту связь. В примере ниже мы проверяем дочерние классы на соответствие родительскому:

class Character: pass
class Hero(Character): pass
class Villain(Character): pass

frodo = Hero()
balrog = Villain()

# проверяем, принадлежат ли они к Character
print("Фродо является персонажем? ", isinstance(frodo, Character))
print("Балрог является персонажем? ", isinstance(balrog, Character))

Запускаем код и видим, что функция увидела родительский класс:

Фродо является персонажем? True
Балрог является персонажем? True

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

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

Такая программа поддерживает два варианта ответов:

# функция принимает и число, и строку
def method(value):
   if isinstance(value, (int, float)):
       print(value, "- это число")
   elif isinstance(value, str):
       print(value, "- это текст")

method(33)
method("Совершеннолетие у хоббитов")

При запуске можно получить два вида результатов:

33 - это число
Совершеннолетие у хоббитов - это текст

Практическое применение

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

Валидация входных данных

С isinstance() есть возможность проверить, ввёл ли пользователь правильный формат данных. Для этого можно написать отдельную функцию API или отследить поступающую информацию от пользователя.

Так может выглядеть функция, которая принимает и проверяет аргумент:

# функция возведения в квадрат с проверкой на число
def function(x):
   # проверяем, что x — число
   if not isinstance(x, (int, float)):
       raise TypeError("Нужно число!")
   return x ** 2

print(function(4))
print(function("четыре"))

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

TypeError: Нужно число!

После этого в консоли появляется результат работы с аргументом правильного типа:

16

Использование в полиморфных функциях

Полиморфизм — это когда один и тот же код работает по-разному с разными объектами.

Для примера с isinstance() мы возьмём такой код: одна и та же функция по-разному реагирует на разные классы. Если очень сильно упростить, то такой же принцип может использоваться в игре — на разных врагов включается разный вид атаки:

class Enemy: pass
class Magician(Enemy): pass

def attack(target):
   if isinstance(target, Magician):
       print("Используем заклинание для атаки мага")
   elif isinstance(target, Enemy):
       print("Обычная атака.")

attack(Magician())

Проверяем, что функция сработала именно на класс Magician:

Используем заклинание для атаки мага

Примеры из реальных проектов

Функция может использоваться в таких задачах:

  • Проверка типов при парсинге JSON-данных.
  • Проверка объектов в системах логирования.
  • Валидация API-входных параметров.

Проверка типов может выглядеть так: мы принимаем данные JSON-формата и просим isinstance() убедиться, что в качестве id в файле стоит целое число:

data = {"id": 1, "name": "Фродо"}

if isinstance(data["id"], int):
   print("Тип данных ID корректный")

Получаем:

Тип данных ID корректный

Особенности и лучшие практики

Функция выглядит просто, но в сочетании с другими инструментами может быть частью серьёзной сложной программы. Особенно интересны возможности использования isinstance() с разными классами.

Когда использовать isinstance(), а когда type()

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

Если брать главное:

Isinstance() нужен для проверки типов объектов
Type() нужен для определения типа объекта и для создания новых классов

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

Isinstance() видит цепочку классов и распознаёт, если один унаследован от другого:

class Rings: pass
class GnomesRing(Rings): pass

gnomes_ring_1 = GnomesRing()
print(isinstance(gnomes_ring_1, Rings))

Результат в терминале показывает, что функция видит начальный класс:

True

Работа с абстрактными базовыми классами

Обычно класс описывает какой-то один конкретный объект. Это может быть всё что угодно: герой игры, животное, турфирма, инструмент плотника.

Абстрактный класс (или ABC) описывает не класс, а свойство объекта. Например, он итерируемый? Этот объект — последовательность? Ведёт ли он себя как «словарь»?

Для этого сначала нужно импортировать модуль abc и нужные абстрактные классы из библиотеки collections:

from collections.abc import Iterable, Sequence

После этого для эксперимента создаём разные типы данных:

# создаём список
a = [1, 2, 3]
# создаём кортеж
b = (1, 2, 3)
# создаём словарь
c = {"hero": "Frodo"}

Теперь можно проверить объекты на итерируемость:

print(isinstance(a, Iterable))
print(isinstance(b, Iterable))
print(isinstance(c, Iterable)) 

Получаем, что итерироваться можно по всем объектам:

True
True
True

Попробуем ещё и проверим, ведут ли себя объекты как последовательности:

# проверяем, ведёт ли себя объект как "последовательность"
print(isinstance(a, Sequence))
print(isinstance(b, Sequence))
print(isinstance(c, Sequence))

Список и кортеж — это последовательности, а словарь — нет:

True
True
False

Частые ошибки и вопросы

Вот ещё несколько полезных вещей про isistance().

Почему isinstance() лучше type()

Instance() не лучше и не хуже, это просто другой инструмент внутри одного языка. Для удобства в Питоне сделано много разных встроенных функций, методов и других инструментов. Каждый из них лучше всего подходит для своей конкретной задачи.

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

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

value = 1.5
print(isinstance(value, (int, float)))

True

Обработка сложных случаев наследования

Функция отслеживает цепочку наследования до первого родительского класса. Если от класса А унаследован класс В, а от класса В — класс С, то isinstance() увидит связь между С и А:

class A: pass
class B(A): pass
class C(B): pass

obj = C()
print(isinstance(obj, A))

Проверяем, что получилось:

True

Бонус для читателей

Если вам интересно погрузиться в мир ИТ и при этом немного сэкономить, держите наш промокод на курсы Практикума. Он даст вам скидку при оплате, поможет с льготной ипотекой и даст безлимит на маркетплейсах. Ладно, окей, это просто скидка, без остального, но хорошая.

Вам может быть интересно
medium