Question

I know that in Python, given a class ClassA, with

inspect.getmembers(ClassA, predicate=inspect.ismethod)

I can iterate over the different methods present in ClassA. Inherited methods are also gathered, which is convenient in my case. But what I would need is, given a particular method method1 of ClassA, to get the class from which ClassA inherited method1. It might be ClassA itself, or any of its parents/grandparents. I thought I could recursively traverse the __bases__ attribute, looking for the method1 attribute at each step. But maybe this functionality is already implemented somewhere. Is there another way?

Was it helpful?

Solution

Look through the MRO (Method Resolution Order), using inspect.getmro() (which works on both old and new-style classes):

def class_for_method(cls, method):
    return next((c for c in inspect.getmro(cls) 
                 if method.__func__ in vars(c).values()), None)

There is currently no stdlib method to do this search for you, no.

Demo:

>>> import inspect
>>> def class_for_method(cls, method):
...     return next((c for c in inspect.getmro(cls) 
...                  if method.__func__ in vars(c).values()), None)
... 
>>> class Base1(object):
...     def foo(self): pass
... 
>>> class Base2(object):
...     pass
... 
>>> class ClassA(Base1, Base2):
...     pass
... 
>>> class_for_method(ClassA, ClassA.foo)
<class '__main__.Base1'>

If no base class is found, the above expression returns None:

>>> class Bar:
...     def spam(): pass
... 
>>> class_for_method(ClassA, Bar.spam) is None
True
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top