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?

Était-ce utile?

La 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top