Класс type

Ранее мы уже встречались с понятием type, называя его функцией, которая возвращает тип объекта. Однако теперь пришло время официально заявить, что type — это класс. Вот его определение из Python:

class type(object):
    """
    type(object) -> the object's type
    type(name, bases, dict, **kwds) -> a new type
    """

Класс type используется для двух целей:

  • Определение типа объекта.
  • Создание нового типа или класса.

Сейчас давайте сосредоточимся на первой задаче — определении типа объектов.


Определение типа объекта

Мы часто использовали класс type для определения типа различных данных в Python. Для этого нужно передать объект внутрь функции type, и результатом будет возвращён его тип. Рассмотрим несколько примеров:

print(type(42))  # <class 'int'>
print(type("Hello"))  # <class 'str'>
print(type([1, 2, 3]))  # <class 'list'>

Мы видим, что type возвращает соответствующий тип данных для каждого объекта.


Определение типа классов и экземпляров

Теперь давайте рассмотрим, как type работает с классами и их экземплярами. Вызов type(instance) вернёт класс, от которого был создан экземпляр:

class Animal:
    pass

class Dog(Animal):
    pass

buddy = Dog()
print(type(buddy))  # <class '__main__.Dog'>

Для каждого экземпляра будет возвращён его исходный класс, от которого он был создан. В данном примере buddy — это экземпляр класса Dog, и результатом вызова type(buddy) является <class '__main__.Dog'>.


Использование type для проверок

Результат вызова type можно использовать для проверок принадлежности экземпляра к определённому классу. Это особенно полезно, когда нужно вызвать метод, который есть только в определённом классе:

class Doctor:
    def diagnose(self):
        print("Diagnosis: Healthy")

class Engineer:
    def build(self):
        print("Building a bridge...")

people = [Doctor(), Engineer(), Doctor()]

for person in people:
    if type(person) is Doctor:
        person.diagnose()
    elif type(person) is Engineer:
        person.build()

Здесь мы проверяем тип каждого объекта в списке и вызываем соответствующий метод в зависимости от класса. Попробуйте закомментировать строчку if type(person) is Doctor: и посмотрите, что произойдёт. Без этой проверки метод diagnose() для экземпляров класса Engineer не будет вызываться, что вызовет ошибку.


Вызов type на самих классах

Интересно то, что type можно вызывать не только на экземплярах классов, но и на самих классах. Давайте рассмотрим такой пример:

class Car:
    pass

print(type(Car))  # <class 'type'>

Результатом вызова type(Car) всегда будет <class 'type'>. Это связано с тем, что все классы в Python являются экземплярами класса type. Почему так происходит, мы обсудим позже в разделе «Метапрограммирование».

class Dog:
    pass

class Cat:
    pass

print(type(Dog))  # <class 'type'>
print(type(Cat))  # <class 'type'>

Обратите внимание, что каждый вызов type возвращает один и тот же результат — класс type, потому что каждый класс, будь то пользовательский или встроенный, создаётся через type.


Атрибуты __class__ и __base__

Теперь давайте рассмотрим два полезных атрибута — __class__ и __base__, которые позволяют нам узнать тип объекта и его родительский класс.


Атрибут __class__

Атрибут __class__ содержит ссылку на класс, с помощью которого был создан объект. Это ещё один способ определения класса объекта, помимо использования функции type:

animal = Animal()
print(animal.__class__)  # <class '__main__.Animal'>

Данный атрибут полезен, когда вам нужно получить ссылку на класс, к которому принадлежит объект, используя прямое обращение через точку.


Атрибут __base__

Атрибут __base__ содержит ссылку на прямого родителя класса. Если у класса нет явного базового класса, то атрибут __base__ будет содержать ссылку на класс object.

Пример:

print(Dog.__base__)  # <class '__main__.Animal'>
print(Animal.__base__)  # <class 'object'>

Здесь класс Dog наследуется от Animal, и атрибут __base__ указывает на это. Для класса Animal, который не наследуется ни от кого (кроме базового класса object), атрибут __base__ содержит ссылку на object.

Для класса object атрибут __base__ возвращает None, поскольку это самый базовый класс:

print(object.__base__)  # None


Пример использования атрибутов

Теперь давайте объединим всё и посмотрим, как эти атрибуты можно использовать:

class Bird:
    pass

class Parrot(Bird):
    pass

polly = Parrot()

# Определение класса объекта
print(polly.__class__)  # <class '__main__.Parrot'>
print(type(polly))  # <class '__main__.Parrot'>

# Определение родительского класса
print(Parrot.__base__)  # <class '__main__.Bird'>
print(Bird.__base__)  # <class 'object'>

Эти атрибуты дают нам гибкие инструменты для работы с иерархией классов и для получения информации о классах и их экземплярах.


классами в Python.

ТемаОписание
Определение типа объектаДля определения типа данных объекта используется функция type(), которая возвращает класс объекта. Примеры: type(42)<class 'int'>, type("Hello")<class 'str'>.
Тип классов и экземпляровВызов type(instance) возвращает класс, от которого был создан экземпляр. Пример: type(buddy) для объекта Dog() возвращает <class '__main__.Dog'>.
Использование type для проверокtype() можно использовать для проверок типа объектов и вызова методов, которые есть только в определённом классе. Пример: цикл, проверяющий, является ли объект экземпляром Doctor или Engineer, и вызывающий соответствующий метод.
Вызов type на классахВызов type() на классах всегда возвращает <class 'type'>, так как все классы в Python являются экземплярами класса type. Пример: type(Car)<class 'type'>.
Атрибут classАтрибут __class__ хранит ссылку на класс, от которого был создан объект. Пример: animal.__class__<class '__main__.Animal'>.
Атрибут baseАтрибут __base__ возвращает прямого родителя класса. Если у класса нет явного базового класса, то атрибут указывает на object. Пример: Dog.__base__<class '__main__.Animal'>, Animal.__base__<class 'object'>.
Пример использования атрибутовПример: polly.__class__ и type(polly) возвращают класс объекта Parrot, а Parrot.__base__ возвращает родителя класса Parrot — класс Bird.

Эта лекция даёт полное представление о классе type, его применениях, а также о полезных атрибутах __class__ и __base__, которые помогают нам глубже понять структуру и связи между классами в Python.

Перейти к следующему шагу

Комментарии