Отличие type() от isinstance()
В чём отличие между этими двумя функциями в python?
Ответы (2 шт):
isinstance учитывает наследование, а type — нет.
Пример:
class Bacon:
pass
class Spam(Bacon):
pass
x = Spam()
type(x) is Spam # True
type(x) is Bacon # False
isinstance(x, Spam) # True
isinstance(x, Bacon) # True
На практике данную особенность можно использовать, чтобы поддерживать полиморфизм.
Допустим, что функция должна менять поведение в зависимости от типа переданных данных. Например, по особому обрабатывать словари:
def f(arg):
if type(arg) is dict:
print('Передан словарь!')
Если передать в неё обычный словарь, всё будет в порядке. Но если передать collections.OrderedDict, всё сломается, несмотря на то, что OrderedDict поддерживает все необходимые методы.
Чтобы избежать этого и обрабатывать все типы, которые наследуются от dict, можно воспользоваться isinstance:
if isinstance(arg, dict):
print('Передан словарь!')
Хотя функция type() возвращает тип переданного аргумента, с ее помощью можно проверить, принадлежит ли аргумент тому или иному типу:
a = 10
b = [1,2,3]
type(a) == int #True
type(b) == list #True
type(a) == float #False
В отличие от type(), функция isinstance() специально создана для проверки принадлежности данных определенному классу (типу данных):
isinstance(a,int) #True
isinstance(b,list) #True
isinstance(b,tuple) #False
c = (4,5,6)
isinstance(c,tuple) #True
Кроме того isinstance() по сравнению с type() позволяет проверить данное на принадлежность хотя бы одному типу из кортежа, переданного в качестве второго аргумента:
isinstance(a,(float, int, str)) #True
isinstance(a,(list, tuple, dict)) #False
Другое отличие isinstance(). Эта функция поддерживает наследование. Для isinstance() экземпляр производного класса также является экземпляром базового класса. Для type() это не так:
class A (list):
pass
a = A()
type(a) == list #False
type(a) == A #True
isinstance(a,A) #True
isinstance(a,list) #True