Python Multi-Inheritance · Examples
Object-Oriented Python

Python Multi-Inheritance Examples

Short, runnable programs that show python multiple inheritance and mro in action. Read the explanation, press Run, then change the code and try your own ideas. New to the topic? Start with the Python Multiple Inheritance and MRO lesson.

1Three mixins, one class

Each mixin adds exactly one skill. Note only has to say which skills it wants. The timestamp is a fixed string here so that the output is the same every time you run it.

Three mixins, one class
import json

class JsonMixin:
    def to_json(self):
        return json.dumps(vars(self), sort_keys=True)

class LoggingMixin:
    def log(self, message):
        print(f"[{type(self).__name__}] {message}")

class TimestampMixin:
    created_at = "2025-03-01 09:30"

    def stamp(self):
        return f"{self.title} created {self.created_at}"

class Note(JsonMixin, LoggingMixin, TimestampMixin):
    def __init__(self, title):
        self.title = title

note = Note("Buy milk")
note.log("note created")
print(note.stamp())
print(note.to_json())
Expected output[Note] note created
Buy milk created 2025-03-01 09:30
{"title": "Buy milk"}

2Find out which class provides a method

The MRO is just a list, so you can walk it yourself. This helper returns the first class whose own namespace contains the name. It is the same search Python performs on every method call.

Find out which class provides a method
class Device:
    def power(self):
        return "on"

class Scanner(Device):
    def scan(self):
        return "scanned"

class Printer(Device):
    def power(self):
        return "printer warming up"

    def print_page(self):
        return "printed"

class OfficeMachine(Scanner, Printer):
    pass

def where_defined(cls, name):
    for klass in cls.__mro__:
        if name in vars(klass):
            return klass.__name__
    return None

for method in ("power", "scan", "print_page", "missing"):
    print(method, "comes from", where_defined(OfficeMachine, method))
print(OfficeMachine().power())
Expected outputpower comes from Printer
scan comes from Scanner
print_page comes from Printer
missing comes from None
printer warming up

3Stacking mixins: the order changes the result

Each mixin calls super().render() and wraps the answer. The class written first is the outermost layer, so swapping the two mixins changes where the quotes and the exclamation mark end up.

Stacking mixins: the order changes the result
class Text:
    def __init__(self, words):
        self.words = words

    def render(self):
        return self.words

class QuoteMixin:
    def render(self):
        return '"' + super().render() + '"'

class ExclaimMixin:
    def render(self):
        return super().render() + "!"

class Announcement(QuoteMixin, ExclaimMixin, Text):
    pass

class Headline(ExclaimMixin, QuoteMixin, Text):
    pass

print(Announcement("hello team").render())
print(Headline("hello team").render())
Expected output"hello team!"
"hello team"!

4Choosing one parent explicitly

When two parents do not share a grandparent, a child can call both of them by name and combine the results. Basic shows the default: only the first parent's method runs.

Choosing one parent explicitly
class Phone:
    def describe(self):
        return "makes calls"

class Camera:
    def describe(self):
        return "takes photos"

class Smartphone(Phone, Camera):
    def describe(self):
        return Phone.describe(self) + " and " + Camera.describe(self)

class Basic(Phone, Camera):
    pass

print("Smartphone", Smartphone().describe())
print("Basic", Basic().describe())
Expected outputSmartphone makes calls and takes photos
Basic makes calls

5isinstance(), __bases__ and __mro__

An object counts as an instance of every parent. __bases__ lists only the parents you wrote in the parentheses, while __mro__ lists the full search order including grandparents.

isinstance(), __bases__ and __mro__
class Swimmer:
    pass

class Flyer:
    pass

class Duck(Swimmer, Flyer):
    pass

duck = Duck()
print(isinstance(duck, Swimmer), isinstance(duck, Flyer))
print([cls.__name__ for cls in Duck.__bases__])
print([cls.__name__ for cls in Duck.__mro__])
print(issubclass(Duck, object))
Expected outputTrue True
['Swimmer', 'Flyer']
['Duck', 'Swimmer', 'Flyer', 'object']
True

Practise next

Python Multiple Inheritance and MRO exercises → Back to the lesson

Python Inheritance examplesPython Polymorphism and Duck Typing examplesPython Composition: Has-A vs Is-A examples