30

How I can get a list with all superclasses of given class in Python?

I know, there is a __subclasses__() method in inspent module for getting all subclasses, but I don't know any similar method for getting superclasses.

bad_coder
  • 11,289
  • 20
  • 44
  • 72
VeLKerr
  • 2,995
  • 3
  • 24
  • 47

2 Answers2

41

Use the __mro__ attribute:

>>> class A:
...     pass
...
>>> class B:
...     pass
...
>>> class C(A, B):
...     pass
...
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

This is a special attribute populated at class instantiation time:

class.__mro__ This attribute is a tuple of classes that are considered when looking for base classes during method resolution.

class.mro() This method can be overridden by a metaclass to customize the method resolution order for its instances. It is called at class instantiation, and its result is stored in __mro__.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • Thanks. And what's the difference between this method and `__mro__` field? Is this better if I'll use `__mro__`? – VeLKerr Jun 24 '15 at 14:12
  • 1
    Thanks. So, it is better to use `__mro__` because it already has a result of `mro()`, which calls at class instantiation. So, I don't need to call `mro()` again. – VeLKerr Jun 24 '15 at 14:24
  • @VeLKerr it is unlikely to make much difference! – jonrsharpe Jun 24 '15 at 14:27
0

Here's 2 methods which work both for python 2 and 3.

Argument can be an instance or a classe.

import inspect

# Works both for python 2 and 3
def getClassName(anObject):    
    if (inspect.isclass(anObject) == False): anObject = anObject.__class__
    className = anObject.__name__
    return className

# Works both for python 2 and 3
def getSuperClassNames(anObject):
    superClassNames = []
    if (inspect.isclass(anObject) == False): anObject = anObject.__class__
    classes = inspect.getmro(anObject)
    for cl in classes:
        s = str(cl).replace('\'', '').replace('>', '')
        if ("__main__." in s): superClassNames.append(s.split('.', 1)[1])
    clName = str(anObject.__name__)
    if (clName in superClassNames): superClassNames.remove(clName)
    if (len(superClassNames) == 0): superClassNames = None
    return superClassNames
prossblad
  • 688
  • 1
  • 7
  • 11