Разница между type() и isinstance()

В этом примере посмотрим, чем отличаются встроенные функции type() и isinstance() и почему при наследовании нужно использовать именно isinstance().

Что нужно знать

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

В чём разница

Разберём отличия type() и isinstance() на коде ниже.

class Polygon:
    def sides_no(self):
        pass

class Triangle(Polygon):
    def area(self):
        pass

obj_polygon = Polygon()
obj_triangle = Triangle()

print(type(obj_triangle) == Triangle)        # true
print(type(obj_triangle) == Polygon)         # false

print(isinstance(obj_polygon, Polygon))      # true
print(isinstance(obj_triangle, Polygon))     # true

Вывод

True
False
True
True

Здесь видно главное: type() смотрит только на сам класс объекта и не учитывает иерархию наследования. Хотя obj_triangle создан от класса Triangle, который унаследован от Polygon, сравнение type(obj_triangle) == Polygon даёт False.

Если нужно проверить, что объект относится к классу или к одному из его потомков, используется isinstance() — она учитывает наследование. Поэтому isinstance(obj_triangle, Polygon) возвращает True: треугольник — это всё-таки многоугольник.