0Pricing
Python Academy · Урок

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

Разберитесь в множественном наследовании и MRO Python: C3-линеаризации.

«Множественное наследование и MRO» — бесплатный урок Python Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Python Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Python Academy содержит 4 уроков всего.

Введение

Python поддерживает множественное наследование. Порядок разрешения методов (MRO) определяет, какой метод вызывается при совпадении имён.

Синтаксис множественного наследования

class C(A, B): наследует от A и B. C получает все методы обоих классов.
class A:
    def hello(self): return 'A'
class B:
    def world(self): return 'B'
class C(A, B): pass
c = C()
print(c.hello(), c.world())

Порядок разрешения методов (MRO)

MRO определяет порядок поиска. C.__mro__ показывает порядок: C, A, B, object. Побеждает первый класс с подходящим методом.
class A:
    def greet(self): return 'A'
class B:
    def greet(self): return 'B'
class C(A, B): pass
print(C().greet())  # A wins
print(C.__mro__)

Линеаризация C3

Python использует линеаризацию C3 для вычисления MRO. Она гарантирует, что дочерний класс идёт перед родительским, а несколько базовых классов — слева направо.
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
print([c.__name__ for c in D.__mro__])

Ромбовидное наследование

D(B,C), где B и C оба наследуют A, создаёт ромбовидную проблему. C3 гарантирует, что __init__ класса A будет вызван только один раз.
class A:
    def __init__(self): print('A')
class B(A):
    def __init__(self): super().__init__(); print('B')
class C(A):
    def __init__(self): super().__init__(); print('C')
class D(B, C):
    def __init__(self): super().__init__(); print('D')
D()

Примеси

Примесь — это класс, предназначенный для множественного наследования. Она добавляет методы, но не выступает самостоятельным полноценным классом.
class JSONMixin:
    def to_json(self):
        import json
        return json.dumps(vars(self))
class User(JSONMixin):
    def __init__(self, name, age): self.name,self.age=name,age
print(User('Alice', 30).to_json())

Правила проектирования примесей

Примеси должны: не иметь __init__, не наследовать классы, не являющиеся примесями, и выполнять одну задачу. Называйте их с суффиксом Mixin.
class LoggingMixin:
    def log(self, msg): print(f'[{self.__class__.__name__}] {msg}')
class Service(LoggingMixin):
    def run(self): self.log('running')
Service().run()

super() при множественном наследовании

super() вызывает следующий класс в MRO, а не обязательно непосредственный родительский класс. Для кооперативного поведения каждый класс должен вызывать super().
class Base:
    def action(self): return 'Base'
class A(Base):
    def action(self): return 'A->' + super().action()
class B(Base):
    def action(self): return 'B->' + super().action()
class C(A, B):
    def action(self): return 'C->' + super().action()
print(C().action())

type() для динамического создания классов

type('NewClass', (Base,), {'method': fn}) динамически создаёт класс. Это полезно для метапрограммирования.
def hello(self): return 'hello'
MyClass = type('MyClass', (object,), {'hello': hello})
print(MyClass().hello())

Проверка MRO

ClassName.__mro__ или inspect.getmro(ClassName) показывает порядок разрешения в виде кортежа классов.
class A: pass
class B(A): pass
class C(B): pass
import inspect
print([c.__name__ for c in inspect.getmro(C)])

Когда следует избегать множественного наследования

В сложных иерархиях множественного наследования трудно разобраться. Предпочитайте композицию или простые примеси глубоким иерархиям.
# Prefer:
class User:
    def __init__(self, name, logger):
        self.name = name
        self.logger = logger  # composition
print('composition preferred')

Быстрая проверка

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

Итоги

Множественное наследование: класс C(A, B). MRO с использованием линеаризации C3 определяет поиск методов. Для аккуратного множественного наследования используйте примеси. super() следует MRO.

Продолжайте

Отличный прогресс! Продолжайте, чтобы освоить следующую концепцию.

Часто задаваемые вопросы

Урок «Множественное наследование и MRO» бесплатный?

Да — полный текст урока «Множественное наследование и MRO» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Python Academy, подпишись на CoddyKit PRO. Курс Python Academy содержит 4 уроков всего.

Чему я научусь в уроке «Множественное наследование и MRO»?

Разберитесь в множественном наследовании и MRO Python: C3-линеаризации. Ты практикуешь Python Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Python Academy?

Предыдущий опыт не требуется. Python Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Множественное наследование и MRO»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Python Academy?

Да. Каждый урок Python Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Одиночное наследование
  2. Переопределение методов и super()
  3. Множественное наследование и MRO
  4. Полиморфизм и утка типизация
← Назад к Python Academy