В Python у нас утиная динамическая типизация, поэтому бывает что нужно узнать тип переменной. Функция type()
возвращает тип аргумента или, учитывая, что в Python – все класс, то класс аргумента. Результат можно сравнить с известным типом:
>>> i, s = 10, "hello" >>> type(i) <class 'int'> >>> type(i) is int True >>> type(s) is str True >>> class A: pass ... >>> a = A() >>> type(a) is A True
Можно создать экземпляр объекта того же класса, что и переменная:
>>> new_a = type(a)() >>> type(new_a) == type(a) True
⚠️ Нужно знать! type()
не принимает во внимание наследование. Тип наследника отличается от типа родителя:
>>> class B(A): pass ... >>> type(A()) is type(B()) False
Лучший способ проверить типы – функция isinstance(x, type)
(instance англ. – экземпляр). Она возвращает True, если первый аргумент является экземпляром класса во втором аргументе:
>>> isinstance(i, int) True >>> isinstance(s, str) True >>> isinstance(a, A) True
Функция поддерживает наследование:
class A: pass class B(A): pass b = B() >>> isinstance(b, A) True
И самое крутое: вторым аргументом допускается передать кортеж из типов, и isinstance
вернет True
, если хоть один из типов в кортеже подходит:
>>> isinstance(i, (int, float)) True >>> isinstance(a, (A, B)) True
Загадка:
class A: ... a = A() class A: ... print(isinstance(a, A))
Правильный ответ был False!
Объяснение. Динамическая натура Python позволяет переопределить класс во время интерпретации. Помните, как недавно я рассказывал про декораторы класса? Там мы подменяли один класс другим. Вот это из той же оперы. Тут мы подменили один класс, другим классом, отвязав имя А
от старого класса и привязав его к новому. Старый класс А
остался жив только как класс объекта в переменной a
. Старого и нового классов разные адреса (id
):
class A: ... print(id(A)) # 140479777819720 a = A() class A: ... print(id(A)) # 140479777809672 isinstance(a, A) # False
Специально для канала @pyway. Подписывайтесь на мой канал в Телеграм @pyway 👈