Reputation: 890
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?
Upvotes: 0
Views: 63
Reputation: 1121774
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
Upvotes: 4