Способы узнать тип данных в языке Python
Способы определения типа переменной
Как точно узнать класс объекта?
Функция type() возвращает точный тип переданного объекта. Это самый прямой метод.
x = 42
print(type(x)) # <class 'int'>
y = "hello"
print(type(y)) # <class 'str'>Python получить тип переменной (определение типа переменной в python)
<class 'int'>
<class 'str'>
тип данных type python (функция type() в python)
Проблема: type() не учитывает иерархию наследования. Если требуется проверить, является ли объект экземпляром родительского класса, type() не подходит.
Как проверить принадлежность к типу с учётом наследования?
Используется функция isinstance(). Она принимает объект и тип (или кортеж типов) и возвращает True, если объект является экземпляром указанного класса или его подкласса.
class Animal:
pass
class Dog(Animal):
pass
dog = Dog()
print(isinstance(dog, Dog)) # True
print(isinstance(dog, Animal)) # True
print(isinstance(dog, (Animal, str))) # True (Animal в кортеже)True
True
True
Ошибка: путают type() и isinstance(). Если требуется точное совпадение класса, лучше type().
Как получить имя типа в виде строки?
Атрибут __class__ даёт доступ к классу объекта. Комбинация type(obj).__name__ возвращает строковое имя.
x = [1, 2, 3]
print(x.__class__) # <class 'list'>
print(type(x).__name__) # 'list'<class 'list'>
list
Внимание: __class__ может быть изменён в редких случаях (например, при использовании слотов).
Как проверить тип с помощью модуля types?
Модуль types содержит имена для встроенных типов (например, types.FunctionType). Это удобно для сравнения без импорта всего класса.
import types
def func(): pass
print(type(func) is types.FunctionType) # TrueTrue
Не подходит для пользовательских классов – для них лучше использовать isinstance.
Как получить тип из аннотации функции?
Функция typing.get_type_hints() возвращает словарь с аннотированными типами. Полезна для проверки входящих аргументов.
from typing import get_type_hints
def greet(name: str) -> str:
return f"Hello, {name}"
hints = get_type_hints(greet)
print(hints) # {'name': <class 'str'>, 'return': <class 'str'>}{'name': <class 'str'>, 'return': <class 'str'>}Аннотации не проверяются во время выполнения автоматически – нужна дополнительная валидация.
Как определить тип в рантайме для generic (обобщённых) типов?
Начиная с Python 3.8, для параметризованных generic (например, list[int]) можно использовать typing.get_origin() и typing.get_args().
from typing import get_origin, get_args, List
t = List[int]
print(get_origin(t)) # <class 'list'>
print(get_args(t)) # (<class 'int'>,)<class 'list'>
(<class 'int'>,)
Generic типы существуют только для аннотаций, в runtime обычный list не хранит информацию о типе элементов.
Расширенные примеры определения типа
# Пример 1: type() с пользовательскими классами
class MyMeta(type):
pass
class MyClass(metaclass=MyMeta):
pass
obj = MyClass()
print(type(obj)) # <class '__main__.MyClass'>
print(type(MyClass)) # <class '__main__.MyMeta'><class '__main__.MyClass'>
<class '__main__.MyMeta'>
# Пример 2: isinstance с абстрактными базовыми классами
from collections.abc import Iterable
print(isinstance([], Iterable)) # True
print(isinstance(42, Iterable)) # FalseTrue
False
# Пример 3: isinstance с кортежем типов для проверки нескольких вариантов
import numbers
def check_number(val):
if isinstance(val, numbers.Number):
return "число"
return "не число"
print(check_number(3+4j)) # число
print(check_number("abc")) # не числочисло
не число
# Пример 4: определение callable (вызываемого объекта)
import inspect
def func(): pass
print(callable(func)) # True
print(inspect.iscoroutine(func)) # False (обычная функция)True
False
# Пример 5: проверка типа с помощью try/except (на примере конвертации строки)
def safe_int(val):
try:
int(val)
return int
except ValueError:
try:
float(val)
return float
except:
return str
print(safe_int("123")) # <class 'int'>
print(safe_int("12.3")) # <class 'float'>
print(safe_int("abc")) # <class 'str'><class 'int'>
<class 'float'>
<class 'str'>
# Пример 6: определение типа в списке с разнородными объектами
mixed = [1, "hello", 3.14, []]
for item in mixed:
print(type(item).__name__, end=" ")
# int str float listint str float list
# Пример 7: использование typing.get_type_hints для самодокументируемости
from typing import get_type_hints, List, Optional
def process(items: List[int], factor: Optional[float] = None) -> bool:
return True
h = get_type_hints(process)
print(h['items']) # typing.List[int]
print(h['factor']) # typing.Optional[float]typing.List[int]
typing.Optional[float]
# Пример 8: проверка родительского класса через __bases__
class Base:
pass
class Child(Base):
pass
print(Child.__bases__) # (<class '__main__.Base'>,)(<class '__main__.Base'>,)