Ранее мы уже встречались с понятием 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.