Как определить тип переменной: обзор методов в Python
Способы определения типа объекта в Python
Основным и наиболее прямым способом получения типа объекта является функция type(). Она возвращает объект типа (класс) переданного аргумента. Альтернативой служит атрибут __class__, доступный у любого объекта. Оба подхода дают одинаковый результат для подавляющего большинства случаев.
x = 42
print(type(x))
print(x.__class__)Get attributes python (получение атрибутов объекта в python)
<class 'int'> <class 'int'>
Python get class (получение класса объекта в python)
Для проверки принадлежности объекта к определённому типу рекомендуется использовать встроенную функцию isinstance(), которая учитывает наследование и корректно работает с абстрактными базовыми классами.
print(isinstance([1,2,3], list)) # True
print(isinstance([1,2,3], object)) # True, так как list наследует objectPython get type (получение типа объекта в python)
Как получить имя типа в виде строки?
Имя типа можно извлечь через атрибут __name__ объекта класса, возвращённого type() или __class__.
t = type(3.14)
print(t.__name__) # 'float'
Это удобно для логирования или отображения пользователю.
Типичная ошибка:
Попытка напрямую обратиться к __name__ у экземпляра (например, 3.14.__name__) вызовет ошибку AttributeError, так как атрибут __name__ определён у класса, а не у экземпляра.
Как проверить, является ли объект экземпляром определённого класса или его подкласса?
Функция isinstance(obj, classinfo) возвращает True, если obj является экземпляром класса classinfo или любого его подкласса. Можно передать кортеж классов для проверки нескольких типов одновременно.
print(isinstance(10, (int, float))) # True
print(isinstance(10, bool)) # False (логический тип наследует int, но isinstance вернёт True, если передать int; отдельная проверка bool - False)
Распространённая проблема:
Использование type(obj) == SomeClass не учитывает наследование. Например, type(True) == int вернёт False, хотя bool является подклассом int. Правильнее применять isinstance.
Как проверить, является ли класс подклассом другого?
Функция issubclass(cls, base) возвращает True, если cls является подклассом base (прямым, косвенным или виртуальным).
print(issubclass(bool, int)) # True
print(issubclass(float, int)) # False
Как получить иерархию наследования класса?
Для просмотра непосредственных базовых классов используется атрибут __bases__, для полного порядка разрешения методов - __mro__ (Method Resolution Order).
class A: pass
class B(A): pass
class C(B): pass
print(C.__bases__) # (<class '__main__.B'>,)
print(C.__mro__) # (<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
Примечание:
При множественном наследовании __bases__ содержит кортеж всех непосредственных родителей. Порядок их перечисления влияет на MRO.
Как сравнить два типа с помощью оператора is?
Оператор is проверяет идентичность объектов. Если нужно убедиться, что тип объекта в точности равен определённому классу (без учёта наследования), можно использовать type(obj) is SomeClass.
print(type(5) is int) # True
print(type(True) is int) # False, хотя bool - подкласс int
Ошибка использования:
Не следует путать оператор is с равенством ==. type(obj) == SomeClass тоже работает, но is считается более идиоматичным для сравнения с синглтонами (типы в Python являются синглтонами).
Как использовать модуль inspect для анализа типов?
Модуль inspect предоставляет функции isclass(), ismodule(), isfunction() и другие, позволяющие проверять принадлежность объекта к определённой категории, а также извлекать его тип и другую метаинформацию.
import inspect
def foo(): pass
print(inspect.isfunction(foo)) # True
print(inspect.isclass(int)) # True
print(inspect.ismodule(math)) # True (при условии import math)
Этот подход особенно полезен при написании декораторов или метапрограммировании, когда требуется проверить природу объекта, а не только его тип.
Расширенные примеры получения и использования типов объектов в Python.
Пример 1: type() для различных встроенных типов.
Функция type() возвращает точный класс объекта. Полезно для отладки и динамического анализа.
print(type(42))
print(type(3.14))
print(type('hello'))
print(type([1,2,3]))
print(type({'a':1}))
print(type(lambda x: x))
<class 'int'> <class 'float'> <class 'str'> <class 'list'> <class 'dict'> <class 'function'>
Пример 2: isinstance с кортежем типов.
Передача кортежа в isinstance позволяет проверить принадлежность к любому из перечисленных типов.
def check_type(value):
if isinstance(value, (int, float, complex)):
print("Числовой тип")
else:
print("Другой тип")
check_type(10)
check_type(3+4j)
check_type("abc")
Числовой тип Числовой тип Другой тип
Пример 3: issubclass и атрибут __bases__.
Демонстрация работы с иерархией классов.
class Animal: pass
class Mammal(Animal): pass
class Dog(Mammal): pass
print(issubclass(Dog, Animal)) # True
print(Dog.__bases__) # (<class '__main__.Mammal'>,)
print(Dog.__mro__) # полный порядок разрешения методов
True (<class '__main__.Mammal'>,) (<class '__main__.Dog'>, <class '__main__.Mammal'>, <class '__main__.Animal'>, <class 'object'>)
Пример 4: Инспекция функций и классов с помощью inspect.
Модуль inspect позволяет различать функции, классы, методы и другие сущности.
import inspect
class MyClass:
def method(self): pass
obj = MyClass()
print(inspect.isclass(MyClass)) # True
print(inspect.ismethod(obj.method)) # False (bound method - не функция)
print(inspect.isfunction(MyClass.method)) # True (unbound)
print(inspect.isroutine(obj.method)) # True (любая вызываемая сущность)
True False True True
Пример 5: Получение аннотаций типов с помощью typing.get_type_hints.
Хотя эта функция не возвращает тип объекта напрямую, она позволяет извлекать аннотации, что полезно для рефлексии.
from typing import get_type_hints
def func(a: int, b: str) -> bool:
return a > 0
hints = get_type_hints(func)
print(hints) # {'a': int, 'b': str, 'return': bool}
{'a': <class 'int'>, 'b': <class 'str'>, 'return': <class 'bool'>}
Пример 6: Использование type() для создания нового класса (метаклассы).
type() с тремя аргументами создаёт новый класс динамически. Это продвинутая техника метапрограммирования.
MyDynamicClass = type('MyDynamicClass', (object,), {'x': 10})
obj = MyDynamicClass()
print(obj.x) # 10
print(type(obj).__name__) # MyDynamicClass
10 MyDynamicClass