How can I get the parent class(es) of a Python class?
Use the following attribute:
cls.__bases__
From the docs:
The tuple of base classes of a class object.
Example:
>>> str.__bases__
(<class 'object'>,)
Another example:
>>> class A(object):
... pass
...
>>> class B(object):
... pass
...
>>> class C(A, B):
... pass
...
>>> C.__bases__
(<class '__main__.A'>, <class '__main__.B'>)
If you want all the ancestors rather than just the immediate ones, use cls.__mro__
.
For versions of Python earlier than 3.5, use inspect.getmro
:
import inspect
print inspect.getmro(cls)
Usefully, this gives you all ancestor classes in the "method resolution order" -- i.e. the order in which the ancestors will be checked when resolving a method (or, actually, any other attribute -- methods and other attributes live in the same namespace in Python, after all;-).
cls.__mro__
(at least in Python 3.5) –
Jodoin cls.mro()
also works –
Archiearchiepiscopacy The fastest way to get all parents, and in order, is to just use the __mro__
built-in.
For instance, repr(YOUR_CLASS.__mro__)
.
The following:
import getpass
getpass.GetPassWarning.__mro__
...outputs, in order:
(<class 'getpass.GetPassWarning'>, <type 'exceptions.UserWarning'>, <type 'exceptions.Warning'>, <type 'exceptions.Exception'>, <type 'exceptions.BaseException'>, <type 'object'>)
There you have it. The "best" answer may have more votes but this is so much simpler than some convoluted for
loop, looking into __bases__
one class at a time, not to mention when a class extends two or more parent classes. Importing and using inspect
just clouds the scope unnecessarily.
inspect.getmro
just calls __mro__
on object, as you can see in github.com/python/cpython/blob/… . Using getmro
produces cleaner and more readable code. Though skipping a function call is indeed faster. –
Pteridophyte isinstance(pre_switch.__class__.__mro__[1], nengo.base.Process)
but it returns False
. –
Tortuga __mro__
also contains the class itself, such that A in A.__mro__ is True
, the same does not hold for __bases__
, so take that in mind if you want to check whether a class is a strict subclass of another. –
Polynomial New-style classes have an mro
method you can call which returns a list of parent classes in method resolution order.
object
doesn't seem to respond to mro
. –
Ong x
, we can get the method resolution order with the call type(x).mro()
we can consider if x
has ClassX
as a base class with: ClassX in type(x).mro()
–
Sacrarium Use bases if you just want to get the parents, use __mro__
(as pointed out by @naught101) for getting the method resolution order (so to know in which order the init's were executed).
Bases (and first getting the class for an existing object):
>>> some_object = "some_text"
>>> some_object.__class__.__bases__
(object,)
For mro in recent Python versions:
>>> some_object = "some_text"
>>> some_object.__class__.__mro__
(str, object)
Obviously, when you already have a class definition, you can just call __mro__
on that directly:
>>> class A(): pass
>>> A.__mro__
(__main__.A, object)
If you want to ensure they all get called, use super
at all levels.
If you have a variable and want to get its class and parent classes use type() method which will give class for a variable
val="happy coding"
print(type(val).__mro__)
Output:
(<class 'str'>, <class 'object'>)
This funciton will print the all the classes of an object, while in each step the next object will the left most parent.
def print_root_left(class_):
while True:
print(class_)
# Check there if are no bases then we have reached the root class
if not class_.__bases__:
break
class_=class_.__bases__[0] # use the left most parent
example = "hello"
print_root_left(example.__class__)
def class_hierarchy(class_name):
import re
ancestor = successor = class_name
level = 0
print ("The", successor, "has the next parents:\n")
while True:
try:
ancestor = re.search(r"'(.*)'", str(successor.__bases__[0]))
print (level, ancestor.group(1))
successor = eval(ancestor.group(1))
level+=1
except:
break
#example
class_hierarchy(IndexError)
© 2022 - 2024 — McMap. All rights reserved.
type(C()).__bases__
as mentioned further below – Indusium