class Flyer:
def fly(self): return 'Flying'
class Swimmer:
def swim(self): return 'Swimming'
class Duck(Flyer, Swimmer):
pass
d = Duck()
print(d.fly(), d.swim()) # Flying Swimming
Topics
20
Async Generators & Async Context Managers
Command-Line Interfaces (argparse)
Comprehensions & Generators
Concurrency (asyncio/threading/multiprocessing)
Data Types & Structures
Dataclasses & NamedTuples
Debugging & Profiling
Decorators
Descriptors & Properties
Exception Handling
File I/O & Context Managers
Functions & Scope
functools & Functional Programming Tools
Iterators & the Iterator Protocol
Logging
Magic Methods & Operator Overloading
Memory Management & Garbage Collection
Metaclasses & Class Customization
Modules & Packaging
Multiple Inheritance & MRO
Multiple Inheritance & MRO
15 questions found
Multiple inheritance lets a class inherit from more than one base class simultaneously, combining attributes and methods from all of them, unlike single inheritance where a class has exactly one direct parent. Python supports this natively via `class Child(Base1, Base2):`, unlike languages like Java that only allow single class inheritance (using interfaces instead).
Real-world example
A game engine's Character class inherits from both Movable and Damageable mixins, combining movement and health mechanics without duplicating code across every character type.
Multiple Inheritance & MRO;Magic Methods & Operator Overloading
The diamond problem occurs when a class inherits from two classes that both inherit from a common ancestor, creating ambiguity about which inherited method version should be used. Python resolves this deterministically using the C3 linearization algorithm to compute a single, consistent Method Resolution Order (MRO), ensuring each ancestor class appears exactly once and in a predictable sequence that respects both local precedence order and each parent's own MRO.
class A:
def greet(self): return 'A'
class B(A):
def greet(self): return 'B'
class C(A):
def greet(self): return 'C'
class D(B, C): # diamond: D -> B,C -> A
pass
print(D().greet()) # 'B' -- follows MRO, not naive depth-first
Real-world example
A framework's mixin-based class hierarchy relies on predictable MRO resolution so that combining LoggingMixin and CachingMixin with a base Service class always calls the expected overridden method.
Multiple Inheritance & MRO;Metaclasses & Class Customization
How does super() work in the context of multiple inheritance, and why is it more than just 'call the parent class'?
Intermediatesuper() doesn't literally mean 'my direct parent class' -- it returns a proxy that follows the class's MRO, calling the *next* class in that order relative to the current class. In multiple inheritance with cooperative super() calls throughout a hierarchy, this enables each class's method to properly chain to the next one in the linearized order, not just its immediate base, making cooperative multiple inheritance work correctly.
class A:
def greet(self):
print('A.greet')
class B(A):
def greet(self):
print('B.greet')
super().greet() # calls next in MRO, not necessarily A directly
class C(A):
def greet(self):
print('C.greet')
super().greet()
class D(B, C):
def greet(self):
print('D.greet')
super().greet()
D().greet() # D.greet B.greet C.greet A.greet -- follows MRO, calls each once
Real-world example
A mixin-heavy Django class-based view relies on every mixin calling super().dispatch() cooperatively, so all mixins in the MRO chain execute in the correct order for a single request.
Multiple Inheritance & MRO;Functions & Scope
C3 linearization merges the MROs of a class's parents plus the list of parents itself, using a rule that a class only appears in the result once all classes that must precede it (per each parent's own MRO and per the declared base-class order) have already been placed. It guarantees three properties: subclasses precede base classes, the local precedence order (order bases are listed) is preserved, and it's monotonic -- the same relative order holds across all related class hierarchies. If no valid linearization exists, Python raises TypeError: Cannot create a consistent 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', 'A', 'object'] -- computed via C3, not simple depth-first
Real-world example
Debugging an unexpected method resolution in a complex mixin hierarchy, a developer manually traces the C3 merge rules to understand exactly why one class's method takes precedence over another's.
Multiple Inheritance & MRO;Metaclasses & Class Customization
What is a mixin class, and how does it differ from a typical base class in multiple inheritance?
IntermediateA mixin is a class designed to provide a specific, self-contained piece of reusable functionality (like serialization, logging, or comparison behavior) to be combined with other classes via multiple inheritance, but is not meant to be instantiated on its own or represent a standalone concept. Mixins typically don't define __init__ and assume they'll be combined with a 'real' base class that provides the primary state and behavior.
class JSONSerializableMixin:
def to_json(self):
import json
return json.dumps(self.__dict__)
class User(JSONSerializableMixin):
def __init__(self, name):
self.name = name
print(User('Alice').to_json()) # {"name": "Alice"}
Real-world example
A web framework provides LoginRequiredMixin and PermissionMixin classes that view classes combine with their primary View base class to add cross-cutting authentication behavior without code duplication.
Multiple Inheritance & MRO;Descriptors & Properties
Why does the convention of listing mixins before the primary base class matter for MRO and method overriding?
AdvancedPython's MRO respects the left-to-right order bases are listed as a tiebreaker (local precedence order), so `class Foo(Mixin, Base):` means Mixin's methods take precedence over Base's when both define the same method name, since Mixin appears first in the MRO. Reversing the order (`class Foo(Base, Mixin):`) would let Base's methods shadow the Mixin's, likely defeating the mixin's purpose of adding or overriding specific behavior.
class LoggingMixin:
def save(self):
print('Logging save')
super().save()
class Base:
def save(self):
print('Base save')
class Model(LoggingMixin, Base): # Mixin first: its save() runs, then chains to Base
pass
Model().save() # Logging save, then Base save
Real-world example
A code review catches a bug where `class View(TemplateMixin, LoginRequiredMixin, View)` accidentally puts the auth mixin after TemplateMixin, causing template rendering to happen before the login check runs.
Multiple Inheritance & MRO;Metaclasses & Class Customization
How do you call a specific ancestor's method explicitly, bypassing the normal MRO-based super() resolution?
IntermediateYou can call a specific base class's method directly by name, e.g., `Base.method(self, ...)`, rather than using super(), which bypasses cooperative MRO chaining entirely and calls exactly that class's implementation. This is sometimes necessary for edge cases but breaks the cooperative multiple inheritance pattern and can cause a method to be skipped or called multiple times if used carelessly alongside other super() calls in the hierarchy.
class A:
def greet(self): print('A')
class B(A):
def greet(self): print('B')
class C(B):
def greet(self):
A.greet(self) # explicitly calls A's version, skipping B entirely
print('C')
C().greet() # A, C -- B.greet was intentionally bypassed
Real-world example
A subclass needs to specifically call a grandparent class's original implementation, skipping an intermediate parent's override, so it calls Grandparent.method(self) directly instead of using super().
Multiple Inheritance & MRO;Exception Handling
Why does Python sometimes raise 'TypeError: Cannot create a consistent method resolution order'?
AdvancedThis error occurs when the C3 linearization algorithm cannot find any ordering of base classes that satisfies all the required constraints simultaneously -- typically caused by listing base classes in an order that contradicts their own inheritance relationships, such as `class C(A, B)` where B is itself a subclass of A, making it impossible to place A before B (required by A being a base of B) while also respecting the declared order (A before B) without contradiction.
class A: pass
class B(A): pass
try:
class C(A, B): # A listed before B, but B already inherits from A
pass
except TypeError as e:
print(e) # Cannot create a consistent MRO for bases A, B
Real-world example
A refactor accidentally reorders a class's base list, introducing this exact contradiction, and the resulting TypeError immediately flags the inheritance structure as invalid before any code even runs.
Multiple Inheritance & MRO;Debugging & Profiling
How does the built-in `object` class relate to every class's MRO, and why does it always appear last?
IntermediateEvery class in Python 3 implicitly inherits from `object` (directly or transitively), which provides default implementations of fundamental magic methods like __init__, __repr__, __eq__, and __hash__. Because every other class is 'more specific' than object, C3 linearization always places object last in the MRO -- it's the common ancestor that every other class's MRO must be consistent with appearing after.
class Foo:
pass
print(Foo.__mro__) # (<class 'Foo'>, <class 'object'>)
print(issubclass(Foo, object)) # True, implicitly
Real-world example
Understanding that object always terminates the MRO clarifies why calling super().__init__() in a deeply nested class hierarchy eventually reaches object.__init__(), which does nothing but must still be part of the chain.
Multiple Inheritance & MRO;Magic Methods & Operator Overloading
How does cooperative multiple inheritance require every class in the hierarchy to call super() consistently, even in __init__?
AdvancedFor multiple inheritance to work correctly with shared behavior (like initialization), every class's __init__ (and other overridden methods) should call super().__init__(*args, **kwargs) rather than assuming a specific direct parent, so the call chains properly through the entire MRO. If any class in the chain omits the super() call, subsequent classes in the MRO are silently skipped, potentially leaving state uninitialized.
class Base:
def __init__(self):
print('Base init')
class Mixin1(Base):
def __init__(self):
print('Mixin1 init')
super().__init__()
class Mixin2(Base):
def __init__(self):
print('Mixin2 init')
super().__init__()
class Combined(Mixin1, Mixin2):
def __init__(self):
print('Combined init')
super().__init__()
Combined() # Combined, Mixin1, Mixin2, Base init -- all run exactly once
Real-world example
A framework's mixin classes all consistently call super().__init__(**kwargs) so that combining any subset of mixins with a base class correctly initializes every class's state without any single mixin needing to know about the others.
Multiple Inheritance & MRO;Functions & Scope
Showing 1–10 of 15