304

How can I get the parent class(es) of a Python class?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
John Smith
  • 12,491
  • 18
  • 65
  • 111

8 Answers8

343

Use the following attribute:

cls.__bases__

From the docs:

The tuple of base classes of a class object.

Example:

>>> str.__bases__
(<type 'basestring'>,)

Another example:

>>> class A(object):
...   pass
... 
>>> class B(object):
...   pass
... 
>>> class C(A, B):
...   pass
... 
>>> C.__bases__
(<class '__main__.A'>, <class '__main__.B'>)
Ayman Hourieh
  • 132,184
  • 23
  • 144
  • 116
141

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;-).

falsePockets
  • 3,826
  • 4
  • 18
  • 37
Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
63

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.

Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
PyTis
  • 1,054
  • 10
  • 13
  • @John Smith https://stackoverflow.com/users/139885/john-smith, I hope you see this answer. If you like it, please let me know with an upvote! – PyTis Mar 26 '19 at 08:43
  • 2
    In fact, `inspect.getmro` just calls `__mro__` on object, as you can see in https://github.com/python/cpython/blob/ded4737989316653469763230036b04513cb62b3/Lib/inspect.py#L486 . Using `getmro` produces cleaner and more readable code. Though skipping a function call is indeed faster. – tna0y Apr 04 '19 at 12:31
  • How can I test if a parent class of an instance is the one I'm expecting? I've tried `isinstance(pre_switch.__class__.__mro__[1], nengo.base.Process)` but it returns `False`. – Thomas Tiotto Oct 01 '20 at 09:14
  • 1
    I'm finding this helpful with climbing the hierarchy of my Sqlalchemy joined table inheritance orm models. Super simple and exactly what I was looking for. – Justin Palmer Apr 26 '21 at 04:43
  • 1
    `__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. – theberzi Jan 17 '23 at 12:03
20

New-style classes have an mro method you can call which returns a list of parent classes in method resolution order.

Rob Bednark
  • 25,981
  • 23
  • 80
  • 125
DasIch
  • 2,549
  • 1
  • 15
  • 23
  • What counts as a new-style class? It seems I can use this with Django models, but anything simply inheriting from `object` doesn't seem to respond to `mro`. – Brian Kung Jun 15 '15 at 14:21
  • 1
    considering an object `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()` – 648trindade Jan 15 '17 at 01:11
19

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)
PascalVKooten
  • 20,643
  • 17
  • 103
  • 160
3

If you want to ensure they all get called, use super at all levels.

Mike Graham
  • 73,987
  • 14
  • 101
  • 130
  • Once you use super you have to use it in all levels anyway, which is why you should document it's use explicitly. Also you might want to know that super doesn't work on every class... – DasIch Apr 10 '10 at 03:57
2

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'>)
Udesh
  • 2,415
  • 2
  • 22
  • 32
1

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__)