You can always access the super-classes of a class by looking in the __bases__ attribute for that class. Given three simple classes A, B, C (which for Py2.7 must inherit from object) :
class A:
def foo():
pass
def bar():
pass
class B:
def biz(): pass
class C(A, B):
pass
You can then iterate through the __bases__ for C and check whether an attribute, function foo (for example), exists in one of these classes.
To do this you can check for membership of foo in the __dict__ that holds the names for each class object in __bases__:
for base in C.__bases__:
if 'foo' in base.__dict__:
print("Attribute: '{}' defined in {}".format("foo", base))
Which prints:
Attribute: 'foo' defined in <class '__main__.A'>
For a more complete and general view:
# get all attributes of class C
vars = [classVar for classVar in dir(C) if not classVar.startswith('__')]
# iterate through all bases:
for base in C.__bases__:
for attr in vars:
if attr in base.__dict__:
print("Attribute: '{}' defined in {}".format(attr, base))
Which returns:
Attribute: 'bar' defined in <class '__main__.A'>
Attribute: 'foo' defined in <class '__main__.A'>
Attribute: 'biz' defined in <class '__main__.B'>
For all classes in the chain of inheritance you can switch __bases__ to __mro__ which indicates the method resolution order; a tuple of objects python searches when trying to resolve attribute references.
If we add a function to class C and make another class D that inherits from C:
class C(A, B):
def another(): pass
class D(C): pass
To get a view of where each function is defined, just switch __bases__ with __mro__ in the loop:
# hold D's attributes (functions names, variables.)
attrs = [var for var in dir(D) if not var.startswith('__')]
# vars contents: ['another', 'bar', 'biz', 'foo']
for base in D.__mro__:
for attr in attrs:
if attr in base.__dict__:
print("Attribute: '{}' defined in {}".format(attr, base))
Now, this follows the mro tuple (equal to (__main__.D, __main__.C, __main__.A, __main__.B, object) in this specific case) and yields a similar output:
Attribute: 'another' defined in <class '__main__.C'>
Attribute: 'bar' defined in <class '__main__.A'>
Attribute: 'foo' defined in <class '__main__.A'>
Attribute: 'biz' defined in <class '__main__.B'>