Python Glossary English

все Python 3ООПпонятие

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

наследование

Python поддерживает множественное наследование. Порядок разрешения методов (MRO) — C3-линеаризация.

Синтаксис

class C(A, B): ...
C.__mro__

super() ведёт не к «родителю», а к следующему классу в __mro__, поэтому при кооперативном наследовании каждый __init__ обязан звать super().__init__() — иначе часть базовых классов молча не отработает. Если из баз нельзя построить непротиворечивый порядок (конфликт C3), Python бросит TypeError прямо на объявлении класса, а не при вызове метода.

Примеры

class A:
    def hello(self):
        return 'A'
class B:
    def hello(self):
        return 'B'
class C(A, B):
    pass
print(C().hello())  # → A (первый в MRO)
print([c.__name__ for c in C.__mro__])  # → ['C', 'A', 'B', 'object']
# Diamond problem
class Base:
    def method(self):
        return 'Base'
class Left(Base):
    def method(self):
        return 'Left+' + super().method()
class Right(Base):
    def method(self):
        return 'Right+' + super().method()
class Diamond(Left, Right):
    pass
print(Diamond().method())  # → Left+Right+Base (каждый Base вызывается раз!)
print([c.__name__ for c in Diamond.__mro__])  # → ['Diamond', 'Left', 'Right', 'Base', 'object']
# Mixin pattern
class JSONMixin:
    def to_json(self):
        import json
        return json.dumps(self.__dict__)
class LogMixin:
    def log(self):
        print(f'{type(self).__name__}: {self.__dict__}')
class User(JSONMixin, LogMixin):
    def __init__(self, name, age):
        self.name = name
        self.age = age
u = User('Alice', 30)
print(u.to_json())  # → {"name": "Alice", "age": 30}
# Проверка MRO
class X: pass
class Y(X): pass
class Z(X): pass
class W(Y, Z): pass
print([c.__name__ for c in W.__mro__])  # → ['W','Y','Z','X','object']
# super() в множественном наследовании
class A:
    def f(self): return ['A']
class B(A):
    def f(self): return ['B'] + super().f()
class C(A):
    def f(self): return ['C'] + super().f()
class D(B, C):
    def f(self): return ['D'] + super().f()
print(D().f())  # → ['D','B','C','A']

См. также

Открыть в полном глоссарииdocs.python.orgСообщить о неточности