I'm new to python and trying to get a list of the classes an object's class inherits from. I'm trying to do this using the bases attribute but I'm not having any success. Can someone please help me out?
def foo(C):
print(list(C.__bases__))
class Thing(object):
def f(self):
print("Yo")
class Shape(Thing):
def l(self):
print("ain't no thang")
class Circle(Shape):
def n(self):
print("ain't no shape")
test = Circle()
foo(test)
4 Answers 4
Only classes have __bases__; class instances do not. You can get the class object through an instance's __class__: use foo(test.__class__) or foo(Circle).
Comments
Use inspect, from documentation
Return a tuple of class cls’s base classes, including cls, in method resolution order. No class appears more than once in this tuple. Note that the method resolution order depends on cls’s type. Unless a very peculiar user-defined metatype is in use, cls will be the first element of the tuple.
>>> import inspect
>>> inspect.getmro(test.__class__)
(<class '__main__.Circle'>, <class '__main__.Shape'>, <class '__main__.Thing'>, <type 'object'>)
>>>
This traverses up the inheritance hierarchy & prints all classes, including object. Pretty Cool eh ?
5 Comments
test.__class__ since test is an instance in his case?test.__class__, was in a hurry to answer :)test.__class__.__mro__ should also work. The reason to use getmro is that it handles old-style classes as well. It first looks for __mro__, and if it doesn't find it, it assumes the class is an old-style class and recursively searches the __bases__ hierarchy. If you don't need that functionality, then you can avoid an import.getmro makes more sense than defining foo as above.print '\n'.join(base.__name__ for base in test.__class__.__bases__)
Or, using the inspect module:
from inspect import getmro
print '\n'.join(base.__name__ for base in getmro(test))
Comments
Your implementation of foo works. But you need to pass a class to foo, not an instance.
In [1]: def foo(C):
...: print(list(C.__bases__))
...:
In [2]: class Thing(object):
...: def f(self):
...: print("Yo")
...:
In [3]: class Shape(Thing):
...: def l(self):
...: print("ain't no thang")
...:
In [4]: class Circle(Shape):
...: def n(self):
...: print("ain't no shape")
...:
In [5]: test = Circle()
In [6]: foo(test)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-6-7b85deb1beaa> in <module>()
----> 1 foo(test)
<ipython-input-1-acd1789d43a9> in foo(C)
1 def foo(C):
----> 2 print(list(C.__bases__))
3
AttributeError: 'Circle' object has no attribute '__bases__'
In [7]: foo(Thing)
[<type 'object'>]
In [8]: foo(Circle)
[<class '__main__.Shape'>]
In [9]: foo(Shape)
[<class '__main__.Thing'>]