List all base classes in a hierarchy of given class?
88,004
Solution 1
inspect.getmro(cls)
works for both new and old style classes and returns the same as NewClass.mro()
: a list of the class and all its ancestor classes, in the order used for method resolution.
>>> class A(object):
>>> pass
>>>
>>> class B(A):
>>> pass
>>>
>>> import inspect
>>> inspect.getmro(B)
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
Solution 2
See the __bases__
property available on a python class
, which contains a tuple of the bases classes:
>>> def classlookup(cls):
... c = list(cls.__bases__)
... for base in c:
... c.extend(classlookup(base))
... return c
...
>>> class A: pass
...
>>> class B(A): pass
...
>>> class C(object, B): pass
...
>>> classlookup(C)
[<type 'object'>, <class __main__.B at 0x00AB7300>, <class __main__.A at 0x00A6D630>]
Solution 3
inspect.getclasstree()
will create a nested list of classes and their bases.
Usage:
inspect.getclasstree(inspect.getmro(IOError)) # Insert your Class instead of IOError.
Solution 4
you can use the __bases__
tuple of the class object:
class A(object, B, C):
def __init__(self):
pass
print A.__bases__
The tuple returned by __bases__
has all its base classes.
Solution 5
According to the Python doc, we can also simply use class.__mro__
attribute or class.mro()
method:
>>> class A:
... pass
...
>>> class B(A):
... pass
...
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
>>> A.__mro__
(<class '__main__.A'>, <class 'object'>)
>>> object.__mro__
(<class 'object'>,)
>>>
>>> B.mro()
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
>>> A.mro()
[<class '__main__.A'>, <class 'object'>]
>>> object.mro()
[<class 'object'>]
>>> A in B.mro()
True
Related videos on Youtube
Author by
Sridhar Ratnakumar
Updated on September 14, 2021Comments
-
Sridhar Ratnakumar over 2 years
Given a class
Foo
(whether it is a new-style class or not), how do you generate all the base classes - anywhere in the inheritance hierarchy - itissubclass
of? -
Sridhar Ratnakumar over 14 yearsThis may introduce duplicates. And this is why the documentation for
getmro
explicitly says "No class appears more than once in this tuple"? -
rbp over 10 yearsDoesn't work for pyobjc classes :( File "/Users/rbp/Projects/zzzzzzz/macmdtypes.py", line 70, in coerce print inspect.getmro(path) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 348, in getmro searchbases(cls, result) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 339, in _searchbases for base in cls.__bases_: AttributeError: 'NSTaggedDate' object has no attribute '__bases'
-
esmit almost 9 years@rbp I suspect that you had the same problem that I encountered: you were trying to do
inspect.getmro(obj)
instead ofinspect.getmro(type(obj))
. -
Bob Stein about 8 yearsCaution,
__bases__
only goes up one level. (As your recursive utility implies, but a cursory glance at the example might not pick up on that.) -
penguin359 over 7 yearsOoh, nice. And for even nicer output, use pprint!
python -c 'import inspect; from pprint import pprint as pp; pp(inspect.getclasstree(inspect.getmro(IOError)))'
-
Boris Verkhovskiy over 4 yearsIf your class inherits from a class that inherits from a class, only the first part of the chain will be in its
__bases__
-
Temperosa almost 4 yearsSimple and clean without importing a whole module for a single function.
-
DavidW over 2 years@Temperosa it maybe be simple and clean but it's wrong
-
ssc over 2 yearsSame thing seems to apply in my case as in @esmit's comment on the answer currently below this one:
type.mro(my_obj)
fails withTypeError: descriptor 'mro' for 'type' objects doesn't apply to a 'my_obj' object
;type.mro(type(my_obj))
works. Not sure if that's relevant:my_obj
is an instance of a Pydantic model.