How to get the parents of a Python class?
Object-Oriented Design practice on Codemia
Turn requirements into classes, and defend the design, on the problems that come up in OOD rounds.
Introduction
Python provides several built-in ways to inspect a class's parent classes (superclasses). The __bases__ attribute gives direct parents, __mro__ (Method Resolution Order) gives the full inheritance chain, and inspect.getmro() provides the same chain via the standard library. Understanding these tools is essential for debugging complex inheritance hierarchies, especially with multiple inheritance and mixins.
bases: Direct Parents Only
__bases__ is a tuple of the direct parent classes, going only one level up. Every class that does not explicitly inherit from anything implicitly inherits from object.
Multiple Inheritance
With multiple inheritance, __bases__ contains all direct parents in the order they were specified.
mro: Full Inheritance Chain
__mro__ (Method Resolution Order) shows the complete chain Python follows when looking up methods. It uses the C3 linearization algorithm to produce a consistent ordering, even with diamond inheritance patterns.
inspect.getmro(): Standard Library Approach
inspect.getmro() returns the same result as __mro__ but works with old-style classes in Python 2 (less relevant now, but the convention persists in many codebases).
issubclass() and isinstance()
Practical: Finding All Parent Methods
Walking the Hierarchy
super() and MRO
super() does not go to the "parent". It goes to the next class in the MRO. This is why B.greet() calls C.greet() (not A.greet()) when called through D.
Common Pitfalls
- Confusing
__bases__with__mro__:__bases__gives only direct parents (one level).__mro__gives the entire chain including grandparents andobject. Use__mro__when you need the full hierarchy. - Assuming
super()calls the direct parent: In multiple inheritance,super()follows the MRO, which may skip to a sibling class before reaching a common ancestor. This is by design (cooperative multiple inheritance). - Checking
__bases__on an instance:__bases__is a class attribute, not an instance attribute. Usetype(instance).__bases__orinstance.__class__.__bases__. - Diamond inheritance without
super(): If parent classes callParentClass.method(self)instead ofsuper().method(), a method in the common ancestor gets called multiple times. Always usesuper()for cooperative inheritance. - Forgetting
objectin the chain: Every class in Python 3 implicitly inherits fromobject. The MRO always ends withobject, which is the root of all classes.
Summary
cls.__bases__returns a tuple of direct parent classescls.__mro__orcls.mro()returns the full Method Resolution Order chaininspect.getmro(cls)provides the same MRO via the standard libraryissubclass(A, B)checks if A is anywhere in B's inheritance treesuper()follows the MRO, not the direct parent. This is important for multiple inheritance- The C3 linearization algorithm ensures a consistent, predictable method lookup order
Related reading
- How to get the type of T from a member of a generic class or method
- How to inject different services at runtime based on a property with Spring without XML
- How to invoke the super constructor in Python?
- How to make a Generic Type Cast function
- How to get the path and name of the Python file that is currently executing?
- How to get the position of a character in Python?
- How to make a Java class that implements one interface with two generic types?
- How to make a Java Generic method static?

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Object-Oriented Design practice on Codemia
Turn requirements into classes, and defend the design, on the problems that come up in OOD rounds.