all Python 3OOPterm
Multiple inheritance / MRO
inheritance
Python supports multiple inheritance. The method resolution order (MRO) is the C3 linearization.
Syntax
class C(A, B): ...
C.__mro__
super() jumps not to "the parent" but to the next class in __mro__, so in cooperative inheritance every __init__ must call super().__init__() or some bases silently never run. If a consistent order can't be built from the bases (a C3 conflict), Python raises TypeError right at the class definition, not when a method is called.
Examples
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']
See also
Open in the full glossarydocs.python.orgReport an inaccuracy