← Назад к вопросам

Как класс type связан с object в Python?

3.0 Senior🔥 151 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Связь type и object в Python

Это фундаментальная концепция метапрограммирования в Python. Отношение циклическое и очень хитрое.

Базовое понимание

class MyClass:
    pass

obj = MyClass()

print(type(obj))       # <class '__main__.MyClass'>
print(type(MyClass))   # <class 'type'>
print(type(type))      # <class 'type'>
print(type(object))    # <class 'type'>

Ключевой момент:

  • type — это метакласс (класс для классов)
  • object — это базовый класс для всех объектов

Иерархия наследования vs Иерархия типов

Наследование (классы расширяют друг друга):

class Animal:
    pass

class Dog(Animal):  # Dog наследует от Animal
    pass

# Dog.__bases__ = (Animal,)
# isinstance(dog_instance, Animal)  # True

Иерархия типов (type и object):

# Все классы наследуют от object
print(MyClass.__bases__)  # (<class 'object>,)

# Все классы являются экземплярами type
print(isinstance(MyClass, type))  # True
print(isinstance(object, type))    # True

# object сам наследует от object (циклически!)
print(object.__bases__)  # ()
# Но object является экземпляром type
print(type(object))  # <class 'type>

Циклические отношения

# type наследует от object
print(type.__bases__)  # (<class 'object>,)

# object является экземпляром type
print(isinstance(object, type))  # True
print(type(object))  # <class 'type>

# type является экземпляром самого себя!
print(isinstance(type, type))  # True
print(type(type))  # <class 'type>

Визуально:

object
  ↑
  |__ type (наследует от object)
       ↑
       |__ type (экземпляр самого себя!)
       ↑
       |__ MyClass (экземпляр type)
            ↑
            |__ my_obj (экземпляр MyClass)

Что type на самом деле делает

type — это метакласс, который создаёт классы. Это эквивалентно:

# Способ 1: обычный синтаксис
class MyClass:
    x = 10
    def method(self):
        pass

# Способ 2: через type (то же самое!)
MyClass = type('MyClass', (), {'x': 10})

# Добавить метод
def method(self):
    pass

MyClass.method = method

MRO (Method Resolution Order)

class A:
    pass

class B(A):
    pass

class C(A):
    pass

class D(B, C):
    pass

print(D.mro())
# [<class 'D>, <class 'B>, <class 'C>, <class 'A>, <class 'object'>]

Все классы в конце цепочки ведут к object. MRO гарантирует, что object — последний в цепи.

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

class Parent:
    pass

class Child(Parent):
    pass

obj = Child()

# type() возвращает класс объекта
print(type(obj))  # <class 'Child>

# Проверить точный тип (без наследования)
if type(obj) is Child:
    print("Exactly Child, not Parent")

# Проверить с наследованием
if isinstance(obj, Parent):
    print("Child is instance of Parent")

Создание собственных метаклассов

class SingletonMeta(type):
    """Метакласс для Singleton паттерна"""
    _instances = {}
    
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class Database(metaclass=SingletonMeta):
    def __init__(self):
        self.connection = None

db1 = Database()
db2 = Database()
print(db1 is db2)  # True — один экземпляр!

Практическое применение

Валидация при создании класса:

class ValidatedMeta(type):
    """Проверяет, что класс имеет docstring"""
    def __new__(mcs, name, bases, namespace):
        if not namespace.get('__doc__'):
            raise TypeError(f"Class {name} must have a docstring!")
        return super().__new__(mcs, name, bases, namespace)

class GoodClass(metaclass=ValidatedMeta):
    """I have docstring"""
    pass

# class BadClass(metaclass=ValidatedMeta):
#     pass  # TypeError!

Итоговая иерархия

object
  ↑
  | наследует от
  |
type (метакласс)
  ↑
  | экземпляр
  |
MyClass
  ↑
  | экземпляр
  |
my_instance

Ключевой вывод:

  • object — базовый класс (почти для всего)
  • type — метакласс (создаёт классы)
  • Все классы наследуют от object
  • Все классы (включая type) являются экземплярами type
  • Это циклические отношения, которые работают благодаря магии Python
Как класс type связан с object в Python? | PrepBro