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

От чего наследуется создаваемый класс, где явно не указан родитель в Python?

1.0 Junior🔥 231 комментариев
#Python Core

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

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

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

Неявное наследование от object в Python

В Python, когда вы создаёте класс без явного указания родительского класса, он автоматически наследуется от встроенного класса object. Это фундаментальный принцип в Python 3 и важная особенность языка.

История: Python 2 vs Python 3

Python 2: Явное и неявное наследование

В Python 2 существовало различие между "старыми" и "новыми" классами:

# Python 2: Старый класс (не наследуется от object)
class OldStyle:
    pass

# Python 2: Новый класс (явно наследуется от object)
class NewStyle(object):
    pass

Python 3: Все классы наследуют от object

В Python 3 это различие исчезло. Все классы автоматически наследуют от object, даже если вы не указываете родителя явно:

# Python 3: Оба варианта эквивалентны
class MyClass:
    pass

# То же самое, что и:
class MyClass(object):
    pass

Где находится класс object?

Класс object — это встроенный класс в Python, входящий в состав модуля builtins:

print(object)  # <class 'object'>
print(type(object))  # <class 'type'>
print(object.__module__)  # builtins

Проверка наследования

Вы можете проверить, что класс наследуется от object несколькими способами:

class SimpleClass:
    pass

# Способ 1: Проверить bases
print(SimpleClass.__bases__)  # (<class 'object'>,)

# Способ 2: Проверить MRO (Method Resolution Order)
print(SimpleClass.__mro__)  # (<class 'SimpleClass'>, <class 'object'>)

# Способ 3: Использовать issubclass()
print(issubclass(SimpleClass, object))  # True

# Способ 4: Использовать isinstance()
obj = SimpleClass()
print(isinstance(obj, object))  # True

Что даёт наследование от object?

Когда класс наследуется от object, он получает доступ к методам и атрибутам базового класса:

Основные методы object

class Person:
    def __init__(self, name):
        self.name = name

person = Person("Иван")

# __init__: Инициализация (переопределяем обычно)
print(person)  # <__main__.Person object at 0x...>

# __str__: Строковое представление
print(str(person))  # <__main__.Person object at 0x...>

# __repr__: Представление для разработчика
print(repr(person))  # <__main__.Person object at 0x...>

# __hash__: Хеширование для словарей и множеств
print(hash(person))  # -9223372036854775808 (примерно)

# __eq__: Сравнение на равенство
print(person == person)  # True
print(person == Person("Иван"))  # False (по умолчанию)

# __new__: Создание объекта
# __class__: Класс объекта
print(person.__class__)  # <class '__main__.Person'>

# __dict__: Словарь атрибутов
print(person.__dict__)  # {'name': 'Иван'}

Полная цепь наследования (MRO)

class Animal:
    pass

class Dog(Animal):
    pass

class Corgi(Dog):
    pass

# Method Resolution Order (MRO) — порядок поиска методов
print(Corgi.__mro__)
# (<class 'Corgi'>, <class 'Dog'>, <class 'Animal'>, <class 'object'>)

# MRO определяет, где Python будет искать методы и атрибуты
for cls in Corgi.__mro__:
    print(cls.__name__)  # Corgi -> Dog -> Animal -> object

Почему object находится в конце цепи?

class Parent:
    def method(self):
        return "Parent"

class Child(Parent):
    def method(self):
        return "Child"

obj = Child()
print(obj.method())  # Child

# Python ищет method в этом порядке:
# 1. Child
# 2. Parent
# 3. object

Практический пример: Переопределение методов object

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __str__(self):
        # Переопределяем метод от object
        return f"Человек по имени {self.name}, {self.age} лет"
    
    def __repr__(self):
        return f"Person(name={self.name!r}, age={self.age!r})"
    
    def __eq__(self, other):
        # Переопределяем сравнение
        if not isinstance(other, Person):
            return False
        return self.name == other.name and self.age == other.age

person1 = Person("Иван", 30)
person2 = Person("Иван", 30)

print(str(person1))  # Человек по имени Иван, 30 лет
print(repr(person1))  # Person(name='Иван', age=30)
print(person1 == person2)  # True

Множественное наследование с object

class Mixin1:
    pass

class Mixin2:
    pass

class MyClass(Mixin1, Mixin2):
    pass

# object всё равно находится в конце цепи
print(MyClass.__mro__)
# (<class 'MyClass'>, <class 'Mixin1'>, <class 'Mixin2'>, <class 'object'>)

Ключевые моменты

  • Все классы в Python 3 наследуют от object — даже если вы не указываете это явно
  • object — это встроенный класс в модуле builtins
  • object находится в конце MRO — Python ищет методы от специфичных классов к базовым
  • object предоставляет базовые методы: __init__, __str__, __repr__, __eq__, __hash__, __new__ и другие
  • Это фундамент ООП в Python — обеспечивает единообразный интерфейс для всех объектов
  • Python 2 отличался — там были старые и новые классы, но это история

Этот дизайн позволяет Python быть консистентным и предсказуемым: любой объект в Python является экземпляром класса, который в конечном итоге наследуется от object.