Курс по Python: https://stepik.org/course/100707
На этом занятии мы поговорим о функции isinstance(), с помощью которой можно выполнять
проверку на принадлежность объекта определенным типам данных.
Например,
объявим переменную:
и для нее
вызовем функцию isinstance(), следующим образом:
Увидим значение True, так как
переменная a действительно
ссылается на целочисленный объект. А вот если указать:
то уже будет
возвращено значение False. Вот так в самом простом варианте
работает эта функция. Но у нее есть один нюанс, связанный с булевым типом
данных. Если определить переменную:
то, очевидно,
функция:
вернет значение True. Однако, если
вместо bool записать int:
то тоже увидим True. Это связано с
особенностью реализацией типа bool. Не буду углубляться в эти детали,
здесь просто достаточно запомнить этот момент. Но тогда спрашивается, а как
отличать тип bool от типа int? Если нужна
строгая проверка на типы, то лучше использовать знакомую нам функцию type() с проверкой
на равенство:
или, используя оператор
is:
Эта функция
различает булевы типы от целочисленных:
Или, если мы
хотим произвести множественную проверку, то воспользоваться оператором in:
type(b) in (bool, float, str)
Здесь мы сразу
проверяем переменную b на три типа данных.
Сейчас у вас
может возникнуть вопрос, зачем нужна функция isinstance(), если проверку типов
можно делать функцией type()? В целом, они действительно очень
похожи, но isinstance() в отличие от type() делает
проверку с учетом иерархии наследования объектов и была разработана для
проверки принадлежности объекта тому или иному классу:
Например, тип bool наследуется от int, поэтому isinstance()
выдает True для обоих типов,
когда b – булева
переменная. А функция type() даст True только для типа
bool. То есть, здесь
проверка происходит без учета иерархии. (Я сейчас не буду углубляться и
объяснять, что такое наследование – это уже раздел ООП и предмет отдельного
курса).
Теперь, когда мы
в целом познакомились с работой функции isinstance(), давайте рассмотрим следующий
пример. Предположим, что у нас есть кортеж с произвольными данными:
data = (4.5, 8.7, True, "книга", 8, 10, -11, [True, False])
И наша задача
вычислить сумму всех вещественных чисел этой коллекции. Для этого, очевидно, вначале
каждый элемент кортежа нужно проверить на вещественный тип данных, а затем, выполнять
суммирование. Я вначале сделаю это через обычный цикл for:
s = 0
for x in data:
if isinstance(x, float):
s += x
print(s)
Как видите, у
нас получилась нужная сумма. Но эту же задачу можно реализовать лучше, с
использованием ранее рассмотренной функции filter():
s = sum(filter(lambda x: isinstance(x, float), data))
Видите, все
записано в одну строчку и, кроме того, работает быстрее, так как используются
встроенные функции вместо цикла for.
А вот если мы
попробуем вычислить сумму целочисленных значений, просто изменив тип данных:
s = sum(filter(lambda x: isinstance(x, int), data))
то увидим
неверное значение 8, так как в коллекции data присутствует
булево значение True, которое интерпретируется как целое число 1. Здесь
лучше применять строгую проверку с использованием функции type():
s = sum(filter(lambda x: type(x) is int, data))
Теперь видим
верное значение 7.
С помощью
функции isinstance() можно делать
и множественные проверки. Например, мы хотим определить, относится ли число к
целому или вещественному типу данных? Для этого достаточно записать кортеж из
этих типов:
a = 5.5
isinstance(a, (int, float))
Это эквивалентно
записи:
isinstance(a, int) or isinstance(a, float)
Но первый
вариант короче и потому чаще используется на практике.
Вот так в Python можно выполнять
проверку типов данных для произвольных объектов. А также знаете отличия между
работой функций isinstance() и type(). До встречи
на следующем уроке.
Курс по Python: https://stepik.org/course/100707